162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * linux/arch/arm/mach-omap2/id.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * OMAP2 CPU identification code
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2005 Nokia Corporation
862306a36Sopenharmony_ci * Written by Tony Lindgren <tony@atomide.com>
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Copyright (C) 2009-11 Texas Instruments
1162306a36Sopenharmony_ci * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/module.h>
1562306a36Sopenharmony_ci#include <linux/kernel.h>
1662306a36Sopenharmony_ci#include <linux/init.h>
1762306a36Sopenharmony_ci#include <linux/io.h>
1862306a36Sopenharmony_ci#include <linux/random.h>
1962306a36Sopenharmony_ci#include <linux/slab.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#ifdef CONFIG_SOC_BUS
2262306a36Sopenharmony_ci#include <linux/sys_soc.h>
2362306a36Sopenharmony_ci#endif
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#include <asm/cputype.h>
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#include "common.h"
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#include "id.h"
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#include "soc.h"
3262306a36Sopenharmony_ci#include "control.h"
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define OMAP4_SILICON_TYPE_STANDARD		0x01
3562306a36Sopenharmony_ci#define OMAP4_SILICON_TYPE_PERFORMANCE		0x02
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define OMAP_SOC_MAX_NAME_LENGTH		16
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic unsigned int omap_revision;
4062306a36Sopenharmony_cistatic char soc_name[OMAP_SOC_MAX_NAME_LENGTH];
4162306a36Sopenharmony_cistatic char soc_rev[OMAP_SOC_MAX_NAME_LENGTH];
4262306a36Sopenharmony_ciu32 omap_features;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ciunsigned int omap_rev(void)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	return omap_revision;
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ciEXPORT_SYMBOL(omap_rev);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciint omap_type(void)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	static u32 val = OMAP2_DEVICETYPE_MASK;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	if (val < OMAP2_DEVICETYPE_MASK)
5562306a36Sopenharmony_ci		return val;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	if (soc_is_omap24xx()) {
5862306a36Sopenharmony_ci		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
5962306a36Sopenharmony_ci	} else if (soc_is_ti81xx()) {
6062306a36Sopenharmony_ci		val = omap_ctrl_readl(TI81XX_CONTROL_STATUS);
6162306a36Sopenharmony_ci	} else if (soc_is_am33xx() || soc_is_am43xx()) {
6262306a36Sopenharmony_ci		val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
6362306a36Sopenharmony_ci	} else if (soc_is_omap34xx()) {
6462306a36Sopenharmony_ci		val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
6562306a36Sopenharmony_ci	} else if (soc_is_omap44xx()) {
6662306a36Sopenharmony_ci		val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
6762306a36Sopenharmony_ci	} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
6862306a36Sopenharmony_ci		val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS);
6962306a36Sopenharmony_ci		val &= OMAP5_DEVICETYPE_MASK;
7062306a36Sopenharmony_ci		val >>= 6;
7162306a36Sopenharmony_ci		goto out;
7262306a36Sopenharmony_ci	} else {
7362306a36Sopenharmony_ci		pr_err("Cannot detect omap type!\n");
7462306a36Sopenharmony_ci		goto out;
7562306a36Sopenharmony_ci	}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	val &= OMAP2_DEVICETYPE_MASK;
7862306a36Sopenharmony_ci	val >>= 8;
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciout:
8162306a36Sopenharmony_ci	return val;
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ciEXPORT_SYMBOL(omap_type);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/*----------------------------------------------------------------------------*/
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#define OMAP_TAP_IDCODE		0x0204
8962306a36Sopenharmony_ci#define OMAP_TAP_DIE_ID_0	0x0218
9062306a36Sopenharmony_ci#define OMAP_TAP_DIE_ID_1	0x021C
9162306a36Sopenharmony_ci#define OMAP_TAP_DIE_ID_2	0x0220
9262306a36Sopenharmony_ci#define OMAP_TAP_DIE_ID_3	0x0224
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci#define OMAP_TAP_DIE_ID_44XX_0	0x0200
9562306a36Sopenharmony_ci#define OMAP_TAP_DIE_ID_44XX_1	0x0208
9662306a36Sopenharmony_ci#define OMAP_TAP_DIE_ID_44XX_2	0x020c
9762306a36Sopenharmony_ci#define OMAP_TAP_DIE_ID_44XX_3	0x0210
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci#define read_tap_reg(reg)	readl_relaxed(tap_base  + (reg))
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cistruct omap_id {
10262306a36Sopenharmony_ci	u16	hawkeye;	/* Silicon type (Hawkeye id) */
10362306a36Sopenharmony_ci	u8	dev;		/* Device type from production_id reg */
10462306a36Sopenharmony_ci	u32	type;		/* Combined type id copied to omap_revision */
10562306a36Sopenharmony_ci};
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/* Register values to detect the OMAP version */
10862306a36Sopenharmony_cistatic struct omap_id omap_ids[] __initdata = {
10962306a36Sopenharmony_ci	{ .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 },
11062306a36Sopenharmony_ci	{ .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 },
11162306a36Sopenharmony_ci	{ .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 },
11262306a36Sopenharmony_ci	{ .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 },
11362306a36Sopenharmony_ci	{ .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 },
11462306a36Sopenharmony_ci	{ .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 },
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic void __iomem *tap_base;
11862306a36Sopenharmony_cistatic u16 tap_prod_id;
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cistatic void omap_get_die_id(struct omap_die_id *odi)
12162306a36Sopenharmony_ci{
12262306a36Sopenharmony_ci	if (soc_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
12362306a36Sopenharmony_ci		odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0);
12462306a36Sopenharmony_ci		odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1);
12562306a36Sopenharmony_ci		odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2);
12662306a36Sopenharmony_ci		odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3);
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci		return;
12962306a36Sopenharmony_ci	}
13062306a36Sopenharmony_ci	odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0);
13162306a36Sopenharmony_ci	odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1);
13262306a36Sopenharmony_ci	odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2);
13362306a36Sopenharmony_ci	odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
13462306a36Sopenharmony_ci}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic int __init omap_feed_randpool(void)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	struct omap_die_id odi;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	/* Throw the die ID into the entropy pool at boot */
14162306a36Sopenharmony_ci	omap_get_die_id(&odi);
14262306a36Sopenharmony_ci	add_device_randomness(&odi, sizeof(odi));
14362306a36Sopenharmony_ci	return 0;
14462306a36Sopenharmony_ci}
14562306a36Sopenharmony_ciomap_device_initcall(omap_feed_randpool);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_civoid __init omap2xxx_check_revision(void)
14862306a36Sopenharmony_ci{
14962306a36Sopenharmony_ci	int i, j;
15062306a36Sopenharmony_ci	u32 idcode, prod_id;
15162306a36Sopenharmony_ci	u16 hawkeye;
15262306a36Sopenharmony_ci	u8  dev_type, rev;
15362306a36Sopenharmony_ci	struct omap_die_id odi;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	idcode = read_tap_reg(OMAP_TAP_IDCODE);
15662306a36Sopenharmony_ci	prod_id = read_tap_reg(tap_prod_id);
15762306a36Sopenharmony_ci	hawkeye = (idcode >> 12) & 0xffff;
15862306a36Sopenharmony_ci	rev = (idcode >> 28) & 0x0f;
15962306a36Sopenharmony_ci	dev_type = (prod_id >> 16) & 0x0f;
16062306a36Sopenharmony_ci	omap_get_die_id(&odi);
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
16362306a36Sopenharmony_ci		 idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
16462306a36Sopenharmony_ci	pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0);
16562306a36Sopenharmony_ci	pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
16662306a36Sopenharmony_ci		 odi.id_1, (odi.id_1 >> 28) & 0xf);
16762306a36Sopenharmony_ci	pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2);
16862306a36Sopenharmony_ci	pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3);
16962306a36Sopenharmony_ci	pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
17062306a36Sopenharmony_ci		 prod_id, dev_type);
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	/* Check hawkeye ids */
17362306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
17462306a36Sopenharmony_ci		if (hawkeye == omap_ids[i].hawkeye)
17562306a36Sopenharmony_ci			break;
17662306a36Sopenharmony_ci	}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	if (i == ARRAY_SIZE(omap_ids)) {
17962306a36Sopenharmony_ci		printk(KERN_ERR "Unknown OMAP CPU id\n");
18062306a36Sopenharmony_ci		return;
18162306a36Sopenharmony_ci	}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
18462306a36Sopenharmony_ci		if (dev_type == omap_ids[j].dev)
18562306a36Sopenharmony_ci			break;
18662306a36Sopenharmony_ci	}
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	if (j == ARRAY_SIZE(omap_ids)) {
18962306a36Sopenharmony_ci		pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n",
19062306a36Sopenharmony_ci		       omap_ids[i].type >> 16);
19162306a36Sopenharmony_ci		j = i;
19262306a36Sopenharmony_ci	}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
19562306a36Sopenharmony_ci	sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	pr_info("%s", soc_name);
19862306a36Sopenharmony_ci	if ((omap_rev() >> 8) & 0x0f)
19962306a36Sopenharmony_ci		pr_cont("%s", soc_rev);
20062306a36Sopenharmony_ci	pr_cont("\n");
20162306a36Sopenharmony_ci}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci#define OMAP3_SHOW_FEATURE(feat)		\
20462306a36Sopenharmony_ci	if (omap3_has_ ##feat())		\
20562306a36Sopenharmony_ci		n += scnprintf(buf + n, sizeof(buf) - n, #feat " ");
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_cistatic void __init omap3_cpuinfo(void)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	const char *cpu_name;
21062306a36Sopenharmony_ci	char buf[64];
21162306a36Sopenharmony_ci	int n = 0;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	memset(buf, 0, sizeof(buf));
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	/*
21662306a36Sopenharmony_ci	 * OMAP3430 and OMAP3530 are assumed to be same.
21762306a36Sopenharmony_ci	 *
21862306a36Sopenharmony_ci	 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
21962306a36Sopenharmony_ci	 * on available features. Upon detection, update the CPU id
22062306a36Sopenharmony_ci	 * and CPU class bits.
22162306a36Sopenharmony_ci	 */
22262306a36Sopenharmony_ci	if (soc_is_omap3630()) {
22362306a36Sopenharmony_ci		if (omap3_has_iva() && omap3_has_sgx()) {
22462306a36Sopenharmony_ci			cpu_name = (omap3_has_isp()) ? "OMAP3630/DM3730" : "OMAP3621";
22562306a36Sopenharmony_ci		} else if (omap3_has_iva()) {
22662306a36Sopenharmony_ci			cpu_name = "DM3725";
22762306a36Sopenharmony_ci		} else if (omap3_has_sgx()) {
22862306a36Sopenharmony_ci			cpu_name = "OMAP3615/AM3715";
22962306a36Sopenharmony_ci		} else {
23062306a36Sopenharmony_ci			cpu_name = (omap3_has_isp()) ? "AM3703" : "OMAP3611";
23162306a36Sopenharmony_ci		}
23262306a36Sopenharmony_ci	} else if (soc_is_am35xx()) {
23362306a36Sopenharmony_ci		cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
23462306a36Sopenharmony_ci	} else if (soc_is_ti816x()) {
23562306a36Sopenharmony_ci		cpu_name = "TI816X";
23662306a36Sopenharmony_ci	} else if (soc_is_am335x()) {
23762306a36Sopenharmony_ci		cpu_name =  "AM335X";
23862306a36Sopenharmony_ci	} else if (soc_is_am437x()) {
23962306a36Sopenharmony_ci		cpu_name =  "AM437x";
24062306a36Sopenharmony_ci	} else if (soc_is_ti814x()) {
24162306a36Sopenharmony_ci		cpu_name = "TI814X";
24262306a36Sopenharmony_ci	} else if (omap3_has_iva() && omap3_has_sgx()) {
24362306a36Sopenharmony_ci		/* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
24462306a36Sopenharmony_ci		cpu_name = "OMAP3430/3530";
24562306a36Sopenharmony_ci	} else if (omap3_has_iva()) {
24662306a36Sopenharmony_ci		cpu_name = "OMAP3525";
24762306a36Sopenharmony_ci	} else if (omap3_has_sgx()) {
24862306a36Sopenharmony_ci		cpu_name = "OMAP3515";
24962306a36Sopenharmony_ci	} else {
25062306a36Sopenharmony_ci		cpu_name = "OMAP3503";
25162306a36Sopenharmony_ci	}
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	scnprintf(soc_name, sizeof(soc_name), "%s", cpu_name);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	/* Print verbose information */
25662306a36Sopenharmony_ci	n += scnprintf(buf, sizeof(buf) - n, "%s %s (", soc_name, soc_rev);
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	OMAP3_SHOW_FEATURE(l2cache);
25962306a36Sopenharmony_ci	OMAP3_SHOW_FEATURE(iva);
26062306a36Sopenharmony_ci	OMAP3_SHOW_FEATURE(sgx);
26162306a36Sopenharmony_ci	OMAP3_SHOW_FEATURE(neon);
26262306a36Sopenharmony_ci	OMAP3_SHOW_FEATURE(isp);
26362306a36Sopenharmony_ci	OMAP3_SHOW_FEATURE(192mhz_clk);
26462306a36Sopenharmony_ci	if (*(buf + n - 1) == ' ')
26562306a36Sopenharmony_ci		n--;
26662306a36Sopenharmony_ci	n += scnprintf(buf + n, sizeof(buf) - n, ")\n");
26762306a36Sopenharmony_ci	pr_info("%s", buf);
26862306a36Sopenharmony_ci}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci#define OMAP3_CHECK_FEATURE(status,feat)				\
27162306a36Sopenharmony_ci	if (((status & OMAP3_ ##feat## _MASK) 				\
27262306a36Sopenharmony_ci		>> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { 	\
27362306a36Sopenharmony_ci		omap_features |= OMAP3_HAS_ ##feat;			\
27462306a36Sopenharmony_ci	}
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_civoid __init omap3xxx_check_features(void)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	u32 status;
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	omap_features = 0;
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS);
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	OMAP3_CHECK_FEATURE(status, L2CACHE);
28562306a36Sopenharmony_ci	OMAP3_CHECK_FEATURE(status, IVA);
28662306a36Sopenharmony_ci	OMAP3_CHECK_FEATURE(status, SGX);
28762306a36Sopenharmony_ci	OMAP3_CHECK_FEATURE(status, NEON);
28862306a36Sopenharmony_ci	OMAP3_CHECK_FEATURE(status, ISP);
28962306a36Sopenharmony_ci	if (soc_is_omap3630())
29062306a36Sopenharmony_ci		omap_features |= OMAP3_HAS_192MHZ_CLK;
29162306a36Sopenharmony_ci	if (soc_is_omap3430() || soc_is_omap3630())
29262306a36Sopenharmony_ci		omap_features |= OMAP3_HAS_IO_WAKEUP;
29362306a36Sopenharmony_ci	if (soc_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
29462306a36Sopenharmony_ci	    omap_rev() == OMAP3430_REV_ES3_1_2)
29562306a36Sopenharmony_ci		omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	omap_features |= OMAP3_HAS_SDRC;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	/*
30062306a36Sopenharmony_ci	 * am35x fixups:
30162306a36Sopenharmony_ci	 * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as
30262306a36Sopenharmony_ci	 *   reserved and therefore return 0 when read.  Unfortunately,
30362306a36Sopenharmony_ci	 *   OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
30462306a36Sopenharmony_ci	 *   mean that a feature is present even though it isn't so clear
30562306a36Sopenharmony_ci	 *   the incorrectly set feature bits.
30662306a36Sopenharmony_ci	 */
30762306a36Sopenharmony_ci	if (soc_is_am35xx())
30862306a36Sopenharmony_ci		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	/*
31162306a36Sopenharmony_ci	 * TODO: Get additional info (where applicable)
31262306a36Sopenharmony_ci	 *       e.g. Size of L2 cache.
31362306a36Sopenharmony_ci	 */
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	omap3_cpuinfo();
31662306a36Sopenharmony_ci}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_civoid __init omap4xxx_check_features(void)
31962306a36Sopenharmony_ci{
32062306a36Sopenharmony_ci	u32 si_type;
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	si_type =
32362306a36Sopenharmony_ci	(read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16) & 0x03;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE)
32662306a36Sopenharmony_ci		omap_features = OMAP4_HAS_PERF_SILICON;
32762306a36Sopenharmony_ci}
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_civoid __init ti81xx_check_features(void)
33062306a36Sopenharmony_ci{
33162306a36Sopenharmony_ci	omap_features = OMAP3_HAS_NEON;
33262306a36Sopenharmony_ci	omap3_cpuinfo();
33362306a36Sopenharmony_ci}
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_civoid __init am33xx_check_features(void)
33662306a36Sopenharmony_ci{
33762306a36Sopenharmony_ci	u32 status;
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	omap_features = OMAP3_HAS_NEON;
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci	status = omap_ctrl_readl(AM33XX_DEV_FEATURE);
34262306a36Sopenharmony_ci	if (status & AM33XX_SGX_MASK)
34362306a36Sopenharmony_ci		omap_features |= OMAP3_HAS_SGX;
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	omap3_cpuinfo();
34662306a36Sopenharmony_ci}
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_civoid __init omap3xxx_check_revision(void)
34962306a36Sopenharmony_ci{
35062306a36Sopenharmony_ci	const char *cpu_rev;
35162306a36Sopenharmony_ci	u32 cpuid, idcode;
35262306a36Sopenharmony_ci	u16 hawkeye;
35362306a36Sopenharmony_ci	u8 rev;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	/*
35662306a36Sopenharmony_ci	 * We cannot access revision registers on ES1.0.
35762306a36Sopenharmony_ci	 * If the processor type is Cortex-A8 and the revision is 0x0
35862306a36Sopenharmony_ci	 * it means its Cortex r0p0 which is 3430 ES1.0.
35962306a36Sopenharmony_ci	 */
36062306a36Sopenharmony_ci	cpuid = read_cpuid_id();
36162306a36Sopenharmony_ci	if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
36262306a36Sopenharmony_ci		omap_revision = OMAP3430_REV_ES1_0;
36362306a36Sopenharmony_ci		cpu_rev = "1.0";
36462306a36Sopenharmony_ci		return;
36562306a36Sopenharmony_ci	}
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	/*
36862306a36Sopenharmony_ci	 * Detection for 34xx ES2.0 and above can be done with just
36962306a36Sopenharmony_ci	 * hawkeye and rev. See TRM 1.5.2 Device Identification.
37062306a36Sopenharmony_ci	 * Note that rev does not map directly to our defined processor
37162306a36Sopenharmony_ci	 * revision numbers as ES1.0 uses value 0.
37262306a36Sopenharmony_ci	 */
37362306a36Sopenharmony_ci	idcode = read_tap_reg(OMAP_TAP_IDCODE);
37462306a36Sopenharmony_ci	hawkeye = (idcode >> 12) & 0xffff;
37562306a36Sopenharmony_ci	rev = (idcode >> 28) & 0xff;
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	switch (hawkeye) {
37862306a36Sopenharmony_ci	case 0xb7ae:
37962306a36Sopenharmony_ci		/* Handle 34xx/35xx devices */
38062306a36Sopenharmony_ci		switch (rev) {
38162306a36Sopenharmony_ci		case 0: /* Take care of early samples */
38262306a36Sopenharmony_ci		case 1:
38362306a36Sopenharmony_ci			omap_revision = OMAP3430_REV_ES2_0;
38462306a36Sopenharmony_ci			cpu_rev = "2.0";
38562306a36Sopenharmony_ci			break;
38662306a36Sopenharmony_ci		case 2:
38762306a36Sopenharmony_ci			omap_revision = OMAP3430_REV_ES2_1;
38862306a36Sopenharmony_ci			cpu_rev = "2.1";
38962306a36Sopenharmony_ci			break;
39062306a36Sopenharmony_ci		case 3:
39162306a36Sopenharmony_ci			omap_revision = OMAP3430_REV_ES3_0;
39262306a36Sopenharmony_ci			cpu_rev = "3.0";
39362306a36Sopenharmony_ci			break;
39462306a36Sopenharmony_ci		case 4:
39562306a36Sopenharmony_ci			omap_revision = OMAP3430_REV_ES3_1;
39662306a36Sopenharmony_ci			cpu_rev = "3.1";
39762306a36Sopenharmony_ci			break;
39862306a36Sopenharmony_ci		case 7:
39962306a36Sopenharmony_ci		default:
40062306a36Sopenharmony_ci			/* Use the latest known revision as default */
40162306a36Sopenharmony_ci			omap_revision = OMAP3430_REV_ES3_1_2;
40262306a36Sopenharmony_ci			cpu_rev = "3.1.2";
40362306a36Sopenharmony_ci		}
40462306a36Sopenharmony_ci		break;
40562306a36Sopenharmony_ci	case 0xb868:
40662306a36Sopenharmony_ci		/*
40762306a36Sopenharmony_ci		 * Handle OMAP/AM 3505/3517 devices
40862306a36Sopenharmony_ci		 *
40962306a36Sopenharmony_ci		 * Set the device to be OMAP3517 here. Actual device
41062306a36Sopenharmony_ci		 * is identified later based on the features.
41162306a36Sopenharmony_ci		 */
41262306a36Sopenharmony_ci		switch (rev) {
41362306a36Sopenharmony_ci		case 0:
41462306a36Sopenharmony_ci			omap_revision = AM35XX_REV_ES1_0;
41562306a36Sopenharmony_ci			cpu_rev = "1.0";
41662306a36Sopenharmony_ci			break;
41762306a36Sopenharmony_ci		case 1:
41862306a36Sopenharmony_ci		default:
41962306a36Sopenharmony_ci			omap_revision = AM35XX_REV_ES1_1;
42062306a36Sopenharmony_ci			cpu_rev = "1.1";
42162306a36Sopenharmony_ci		}
42262306a36Sopenharmony_ci		break;
42362306a36Sopenharmony_ci	case 0xb891:
42462306a36Sopenharmony_ci		/* Handle 36xx devices */
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci		switch(rev) {
42762306a36Sopenharmony_ci		case 0: /* Take care of early samples */
42862306a36Sopenharmony_ci			omap_revision = OMAP3630_REV_ES1_0;
42962306a36Sopenharmony_ci			cpu_rev = "1.0";
43062306a36Sopenharmony_ci			break;
43162306a36Sopenharmony_ci		case 1:
43262306a36Sopenharmony_ci			omap_revision = OMAP3630_REV_ES1_1;
43362306a36Sopenharmony_ci			cpu_rev = "1.1";
43462306a36Sopenharmony_ci			break;
43562306a36Sopenharmony_ci		case 2:
43662306a36Sopenharmony_ci		default:
43762306a36Sopenharmony_ci			omap_revision = OMAP3630_REV_ES1_2;
43862306a36Sopenharmony_ci			cpu_rev = "1.2";
43962306a36Sopenharmony_ci		}
44062306a36Sopenharmony_ci		break;
44162306a36Sopenharmony_ci	case 0xb81e:
44262306a36Sopenharmony_ci		switch (rev) {
44362306a36Sopenharmony_ci		case 0:
44462306a36Sopenharmony_ci			omap_revision = TI8168_REV_ES1_0;
44562306a36Sopenharmony_ci			cpu_rev = "1.0";
44662306a36Sopenharmony_ci			break;
44762306a36Sopenharmony_ci		case 1:
44862306a36Sopenharmony_ci			omap_revision = TI8168_REV_ES1_1;
44962306a36Sopenharmony_ci			cpu_rev = "1.1";
45062306a36Sopenharmony_ci			break;
45162306a36Sopenharmony_ci		case 2:
45262306a36Sopenharmony_ci			omap_revision = TI8168_REV_ES2_0;
45362306a36Sopenharmony_ci			cpu_rev = "2.0";
45462306a36Sopenharmony_ci			break;
45562306a36Sopenharmony_ci		case 3:
45662306a36Sopenharmony_ci		default:
45762306a36Sopenharmony_ci			omap_revision = TI8168_REV_ES2_1;
45862306a36Sopenharmony_ci			cpu_rev = "2.1";
45962306a36Sopenharmony_ci		}
46062306a36Sopenharmony_ci		break;
46162306a36Sopenharmony_ci	case 0xb944:
46262306a36Sopenharmony_ci		switch (rev) {
46362306a36Sopenharmony_ci		case 0:
46462306a36Sopenharmony_ci			omap_revision = AM335X_REV_ES1_0;
46562306a36Sopenharmony_ci			cpu_rev = "1.0";
46662306a36Sopenharmony_ci			break;
46762306a36Sopenharmony_ci		case 1:
46862306a36Sopenharmony_ci			omap_revision = AM335X_REV_ES2_0;
46962306a36Sopenharmony_ci			cpu_rev = "2.0";
47062306a36Sopenharmony_ci			break;
47162306a36Sopenharmony_ci		case 2:
47262306a36Sopenharmony_ci		default:
47362306a36Sopenharmony_ci			omap_revision = AM335X_REV_ES2_1;
47462306a36Sopenharmony_ci			cpu_rev = "2.1";
47562306a36Sopenharmony_ci			break;
47662306a36Sopenharmony_ci		}
47762306a36Sopenharmony_ci		break;
47862306a36Sopenharmony_ci	case 0xb98c:
47962306a36Sopenharmony_ci		switch (rev) {
48062306a36Sopenharmony_ci		case 0:
48162306a36Sopenharmony_ci			omap_revision = AM437X_REV_ES1_0;
48262306a36Sopenharmony_ci			cpu_rev = "1.0";
48362306a36Sopenharmony_ci			break;
48462306a36Sopenharmony_ci		case 1:
48562306a36Sopenharmony_ci			omap_revision = AM437X_REV_ES1_1;
48662306a36Sopenharmony_ci			cpu_rev = "1.1";
48762306a36Sopenharmony_ci			break;
48862306a36Sopenharmony_ci		case 2:
48962306a36Sopenharmony_ci		default:
49062306a36Sopenharmony_ci			omap_revision = AM437X_REV_ES1_2;
49162306a36Sopenharmony_ci			cpu_rev = "1.2";
49262306a36Sopenharmony_ci			break;
49362306a36Sopenharmony_ci		}
49462306a36Sopenharmony_ci		break;
49562306a36Sopenharmony_ci	case 0xb8f2:
49662306a36Sopenharmony_ci	case 0xb968:
49762306a36Sopenharmony_ci		switch (rev) {
49862306a36Sopenharmony_ci		case 0:
49962306a36Sopenharmony_ci		case 1:
50062306a36Sopenharmony_ci			omap_revision = TI8148_REV_ES1_0;
50162306a36Sopenharmony_ci			cpu_rev = "1.0";
50262306a36Sopenharmony_ci			break;
50362306a36Sopenharmony_ci		case 2:
50462306a36Sopenharmony_ci			omap_revision = TI8148_REV_ES2_0;
50562306a36Sopenharmony_ci			cpu_rev = "2.0";
50662306a36Sopenharmony_ci			break;
50762306a36Sopenharmony_ci		case 3:
50862306a36Sopenharmony_ci		default:
50962306a36Sopenharmony_ci			omap_revision = TI8148_REV_ES2_1;
51062306a36Sopenharmony_ci			cpu_rev = "2.1";
51162306a36Sopenharmony_ci			break;
51262306a36Sopenharmony_ci		}
51362306a36Sopenharmony_ci		break;
51462306a36Sopenharmony_ci	default:
51562306a36Sopenharmony_ci		/* Unknown default to latest silicon rev as default */
51662306a36Sopenharmony_ci		omap_revision = OMAP3630_REV_ES1_2;
51762306a36Sopenharmony_ci		cpu_rev = "1.2";
51862306a36Sopenharmony_ci		pr_warn("Warning: unknown chip type: hawkeye %04x, assuming OMAP3630ES1.2\n",
51962306a36Sopenharmony_ci			hawkeye);
52062306a36Sopenharmony_ci	}
52162306a36Sopenharmony_ci	sprintf(soc_rev, "ES%s", cpu_rev);
52262306a36Sopenharmony_ci}
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_civoid __init omap4xxx_check_revision(void)
52562306a36Sopenharmony_ci{
52662306a36Sopenharmony_ci	u32 idcode;
52762306a36Sopenharmony_ci	u16 hawkeye;
52862306a36Sopenharmony_ci	u8 rev;
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	/*
53162306a36Sopenharmony_ci	 * The IC rev detection is done with hawkeye and rev.
53262306a36Sopenharmony_ci	 * Note that rev does not map directly to defined processor
53362306a36Sopenharmony_ci	 * revision numbers as ES1.0 uses value 0.
53462306a36Sopenharmony_ci	 */
53562306a36Sopenharmony_ci	idcode = read_tap_reg(OMAP_TAP_IDCODE);
53662306a36Sopenharmony_ci	hawkeye = (idcode >> 12) & 0xffff;
53762306a36Sopenharmony_ci	rev = (idcode >> 28) & 0xf;
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci	/*
54062306a36Sopenharmony_ci	 * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
54162306a36Sopenharmony_ci	 * Use ARM register to detect the correct ES version
54262306a36Sopenharmony_ci	 */
54362306a36Sopenharmony_ci	if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) {
54462306a36Sopenharmony_ci		idcode = read_cpuid_id();
54562306a36Sopenharmony_ci		rev = (idcode & 0xf) - 1;
54662306a36Sopenharmony_ci	}
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	switch (hawkeye) {
54962306a36Sopenharmony_ci	case 0xb852:
55062306a36Sopenharmony_ci		switch (rev) {
55162306a36Sopenharmony_ci		case 0:
55262306a36Sopenharmony_ci			omap_revision = OMAP4430_REV_ES1_0;
55362306a36Sopenharmony_ci			break;
55462306a36Sopenharmony_ci		case 1:
55562306a36Sopenharmony_ci		default:
55662306a36Sopenharmony_ci			omap_revision = OMAP4430_REV_ES2_0;
55762306a36Sopenharmony_ci		}
55862306a36Sopenharmony_ci		break;
55962306a36Sopenharmony_ci	case 0xb95c:
56062306a36Sopenharmony_ci		switch (rev) {
56162306a36Sopenharmony_ci		case 3:
56262306a36Sopenharmony_ci			omap_revision = OMAP4430_REV_ES2_1;
56362306a36Sopenharmony_ci			break;
56462306a36Sopenharmony_ci		case 4:
56562306a36Sopenharmony_ci			omap_revision = OMAP4430_REV_ES2_2;
56662306a36Sopenharmony_ci			break;
56762306a36Sopenharmony_ci		case 6:
56862306a36Sopenharmony_ci		default:
56962306a36Sopenharmony_ci			omap_revision = OMAP4430_REV_ES2_3;
57062306a36Sopenharmony_ci		}
57162306a36Sopenharmony_ci		break;
57262306a36Sopenharmony_ci	case 0xb94e:
57362306a36Sopenharmony_ci		switch (rev) {
57462306a36Sopenharmony_ci		case 0:
57562306a36Sopenharmony_ci			omap_revision = OMAP4460_REV_ES1_0;
57662306a36Sopenharmony_ci			break;
57762306a36Sopenharmony_ci		case 2:
57862306a36Sopenharmony_ci		default:
57962306a36Sopenharmony_ci			omap_revision = OMAP4460_REV_ES1_1;
58062306a36Sopenharmony_ci			break;
58162306a36Sopenharmony_ci		}
58262306a36Sopenharmony_ci		break;
58362306a36Sopenharmony_ci	case 0xb975:
58462306a36Sopenharmony_ci		switch (rev) {
58562306a36Sopenharmony_ci		case 0:
58662306a36Sopenharmony_ci		default:
58762306a36Sopenharmony_ci			omap_revision = OMAP4470_REV_ES1_0;
58862306a36Sopenharmony_ci			break;
58962306a36Sopenharmony_ci		}
59062306a36Sopenharmony_ci		break;
59162306a36Sopenharmony_ci	default:
59262306a36Sopenharmony_ci		/* Unknown default to latest silicon rev as default */
59362306a36Sopenharmony_ci		omap_revision = OMAP4430_REV_ES2_3;
59462306a36Sopenharmony_ci	}
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
59762306a36Sopenharmony_ci	sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
59862306a36Sopenharmony_ci						(omap_rev() >> 8) & 0xf);
59962306a36Sopenharmony_ci	pr_info("%s %s\n", soc_name, soc_rev);
60062306a36Sopenharmony_ci}
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_civoid __init omap5xxx_check_revision(void)
60362306a36Sopenharmony_ci{
60462306a36Sopenharmony_ci	u32 idcode;
60562306a36Sopenharmony_ci	u16 hawkeye;
60662306a36Sopenharmony_ci	u8 rev;
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci	idcode = read_tap_reg(OMAP_TAP_IDCODE);
60962306a36Sopenharmony_ci	hawkeye = (idcode >> 12) & 0xffff;
61062306a36Sopenharmony_ci	rev = (idcode >> 28) & 0xff;
61162306a36Sopenharmony_ci	switch (hawkeye) {
61262306a36Sopenharmony_ci	case 0xb942:
61362306a36Sopenharmony_ci		switch (rev) {
61462306a36Sopenharmony_ci		case 0:
61562306a36Sopenharmony_ci			/* No support for ES1.0 Test chip */
61662306a36Sopenharmony_ci			BUG();
61762306a36Sopenharmony_ci		case 1:
61862306a36Sopenharmony_ci		default:
61962306a36Sopenharmony_ci			omap_revision = OMAP5430_REV_ES2_0;
62062306a36Sopenharmony_ci		}
62162306a36Sopenharmony_ci		break;
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	case 0xb998:
62462306a36Sopenharmony_ci		switch (rev) {
62562306a36Sopenharmony_ci		case 0:
62662306a36Sopenharmony_ci			/* No support for ES1.0 Test chip */
62762306a36Sopenharmony_ci			BUG();
62862306a36Sopenharmony_ci		case 1:
62962306a36Sopenharmony_ci		default:
63062306a36Sopenharmony_ci			omap_revision = OMAP5432_REV_ES2_0;
63162306a36Sopenharmony_ci		}
63262306a36Sopenharmony_ci		break;
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci	default:
63562306a36Sopenharmony_ci		/* Unknown default to latest silicon rev as default*/
63662306a36Sopenharmony_ci		omap_revision = OMAP5430_REV_ES2_0;
63762306a36Sopenharmony_ci	}
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
64062306a36Sopenharmony_ci	sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf);
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci	pr_info("%s %s\n", soc_name, soc_rev);
64362306a36Sopenharmony_ci}
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_civoid __init dra7xxx_check_revision(void)
64662306a36Sopenharmony_ci{
64762306a36Sopenharmony_ci	u32 idcode;
64862306a36Sopenharmony_ci	u16 hawkeye;
64962306a36Sopenharmony_ci	u8 rev, package;
65062306a36Sopenharmony_ci	struct omap_die_id odi;
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci	omap_get_die_id(&odi);
65362306a36Sopenharmony_ci	package = (odi.id_2 >> 16) & 0x3;
65462306a36Sopenharmony_ci	idcode = read_tap_reg(OMAP_TAP_IDCODE);
65562306a36Sopenharmony_ci	hawkeye = (idcode >> 12) & 0xffff;
65662306a36Sopenharmony_ci	rev = (idcode >> 28) & 0xff;
65762306a36Sopenharmony_ci	switch (hawkeye) {
65862306a36Sopenharmony_ci	case 0xbb50:
65962306a36Sopenharmony_ci		switch (rev) {
66062306a36Sopenharmony_ci		case 0:
66162306a36Sopenharmony_ci		default:
66262306a36Sopenharmony_ci			switch (package) {
66362306a36Sopenharmony_ci			case 0x2:
66462306a36Sopenharmony_ci				omap_revision = DRA762_ABZ_REV_ES1_0;
66562306a36Sopenharmony_ci				break;
66662306a36Sopenharmony_ci			case 0x3:
66762306a36Sopenharmony_ci				omap_revision = DRA762_ACD_REV_ES1_0;
66862306a36Sopenharmony_ci				break;
66962306a36Sopenharmony_ci			default:
67062306a36Sopenharmony_ci				omap_revision = DRA762_REV_ES1_0;
67162306a36Sopenharmony_ci				break;
67262306a36Sopenharmony_ci			}
67362306a36Sopenharmony_ci			break;
67462306a36Sopenharmony_ci		}
67562306a36Sopenharmony_ci		break;
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci	case 0xb990:
67862306a36Sopenharmony_ci		switch (rev) {
67962306a36Sopenharmony_ci		case 0:
68062306a36Sopenharmony_ci			omap_revision = DRA752_REV_ES1_0;
68162306a36Sopenharmony_ci			break;
68262306a36Sopenharmony_ci		case 1:
68362306a36Sopenharmony_ci			omap_revision = DRA752_REV_ES1_1;
68462306a36Sopenharmony_ci			break;
68562306a36Sopenharmony_ci		case 2:
68662306a36Sopenharmony_ci		default:
68762306a36Sopenharmony_ci			omap_revision = DRA752_REV_ES2_0;
68862306a36Sopenharmony_ci			break;
68962306a36Sopenharmony_ci		}
69062306a36Sopenharmony_ci		break;
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	case 0xb9bc:
69362306a36Sopenharmony_ci		switch (rev) {
69462306a36Sopenharmony_ci		case 0:
69562306a36Sopenharmony_ci			omap_revision = DRA722_REV_ES1_0;
69662306a36Sopenharmony_ci			break;
69762306a36Sopenharmony_ci		case 1:
69862306a36Sopenharmony_ci			omap_revision = DRA722_REV_ES2_0;
69962306a36Sopenharmony_ci			break;
70062306a36Sopenharmony_ci		case 2:
70162306a36Sopenharmony_ci		default:
70262306a36Sopenharmony_ci			omap_revision = DRA722_REV_ES2_1;
70362306a36Sopenharmony_ci			break;
70462306a36Sopenharmony_ci		}
70562306a36Sopenharmony_ci		break;
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci	default:
70862306a36Sopenharmony_ci		/* Unknown default to latest silicon rev as default*/
70962306a36Sopenharmony_ci		pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%x)\n",
71062306a36Sopenharmony_ci			__func__, idcode, hawkeye, rev);
71162306a36Sopenharmony_ci		omap_revision = DRA752_REV_ES2_0;
71262306a36Sopenharmony_ci	}
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	sprintf(soc_name, "DRA%03x", omap_rev() >> 16);
71562306a36Sopenharmony_ci	sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
71662306a36Sopenharmony_ci		(omap_rev() >> 8) & 0xf);
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci	pr_info("%s %s\n", soc_name, soc_rev);
71962306a36Sopenharmony_ci}
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci/*
72262306a36Sopenharmony_ci * Set up things for map_io and processor detection later on. Gets called
72362306a36Sopenharmony_ci * pretty much first thing from board init. For multi-omap, this gets
72462306a36Sopenharmony_ci * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to
72562306a36Sopenharmony_ci * detect the exact revision later on in omap2_detect_revision() once map_io
72662306a36Sopenharmony_ci * is done.
72762306a36Sopenharmony_ci */
72862306a36Sopenharmony_civoid __init omap2_set_globals_tap(u32 class, void __iomem *tap)
72962306a36Sopenharmony_ci{
73062306a36Sopenharmony_ci	omap_revision = class;
73162306a36Sopenharmony_ci	tap_base = tap;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	/* XXX What is this intended to do? */
73462306a36Sopenharmony_ci	if (soc_is_omap34xx())
73562306a36Sopenharmony_ci		tap_prod_id = 0x0210;
73662306a36Sopenharmony_ci	else
73762306a36Sopenharmony_ci		tap_prod_id = 0x0208;
73862306a36Sopenharmony_ci}
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci#ifdef CONFIG_SOC_BUS
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_cistatic const char * const omap_types[] = {
74362306a36Sopenharmony_ci	[OMAP2_DEVICE_TYPE_TEST]	= "TST",
74462306a36Sopenharmony_ci	[OMAP2_DEVICE_TYPE_EMU]		= "EMU",
74562306a36Sopenharmony_ci	[OMAP2_DEVICE_TYPE_SEC]		= "HS",
74662306a36Sopenharmony_ci	[OMAP2_DEVICE_TYPE_GP]		= "GP",
74762306a36Sopenharmony_ci	[OMAP2_DEVICE_TYPE_BAD]		= "BAD",
74862306a36Sopenharmony_ci};
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_cistatic const char * __init omap_get_family(void)
75162306a36Sopenharmony_ci{
75262306a36Sopenharmony_ci	if (soc_is_omap24xx())
75362306a36Sopenharmony_ci		return kasprintf(GFP_KERNEL, "OMAP2");
75462306a36Sopenharmony_ci	else if (soc_is_omap34xx())
75562306a36Sopenharmony_ci		return kasprintf(GFP_KERNEL, "OMAP3");
75662306a36Sopenharmony_ci	else if (soc_is_omap44xx())
75762306a36Sopenharmony_ci		return kasprintf(GFP_KERNEL, "OMAP4");
75862306a36Sopenharmony_ci	else if (soc_is_omap54xx())
75962306a36Sopenharmony_ci		return kasprintf(GFP_KERNEL, "OMAP5");
76062306a36Sopenharmony_ci	else if (soc_is_am33xx() || soc_is_am335x())
76162306a36Sopenharmony_ci		return kasprintf(GFP_KERNEL, "AM33xx");
76262306a36Sopenharmony_ci	else if (soc_is_am43xx())
76362306a36Sopenharmony_ci		return kasprintf(GFP_KERNEL, "AM43xx");
76462306a36Sopenharmony_ci	else if (soc_is_dra7xx())
76562306a36Sopenharmony_ci		return kasprintf(GFP_KERNEL, "DRA7");
76662306a36Sopenharmony_ci	else
76762306a36Sopenharmony_ci		return kasprintf(GFP_KERNEL, "Unknown");
76862306a36Sopenharmony_ci}
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_cistatic ssize_t
77162306a36Sopenharmony_citype_show(struct device *dev, struct device_attribute *attr, char *buf)
77262306a36Sopenharmony_ci{
77362306a36Sopenharmony_ci	return sprintf(buf, "%s\n", omap_types[omap_type()]);
77462306a36Sopenharmony_ci}
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_cistatic DEVICE_ATTR_RO(type);
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_cistatic struct attribute *omap_soc_attrs[] = {
77962306a36Sopenharmony_ci	&dev_attr_type.attr,
78062306a36Sopenharmony_ci	NULL
78162306a36Sopenharmony_ci};
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ciATTRIBUTE_GROUPS(omap_soc);
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_civoid __init omap_soc_device_init(void)
78662306a36Sopenharmony_ci{
78762306a36Sopenharmony_ci	struct soc_device *soc_dev;
78862306a36Sopenharmony_ci	struct soc_device_attribute *soc_dev_attr;
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
79162306a36Sopenharmony_ci	if (!soc_dev_attr)
79262306a36Sopenharmony_ci		return;
79362306a36Sopenharmony_ci
79462306a36Sopenharmony_ci	soc_dev_attr->machine  = soc_name;
79562306a36Sopenharmony_ci	soc_dev_attr->family   = omap_get_family();
79662306a36Sopenharmony_ci	if (!soc_dev_attr->family) {
79762306a36Sopenharmony_ci		kfree(soc_dev_attr);
79862306a36Sopenharmony_ci		return;
79962306a36Sopenharmony_ci	}
80062306a36Sopenharmony_ci	soc_dev_attr->revision = soc_rev;
80162306a36Sopenharmony_ci	soc_dev_attr->custom_attr_group = omap_soc_groups[0];
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci	soc_dev = soc_device_register(soc_dev_attr);
80462306a36Sopenharmony_ci	if (IS_ERR(soc_dev)) {
80562306a36Sopenharmony_ci		kfree(soc_dev_attr->family);
80662306a36Sopenharmony_ci		kfree(soc_dev_attr);
80762306a36Sopenharmony_ci		return;
80862306a36Sopenharmony_ci	}
80962306a36Sopenharmony_ci}
81062306a36Sopenharmony_ci#endif /* CONFIG_SOC_BUS */
811