Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f946738c authored by Linus Walleij's avatar Linus Walleij Committed by Russell King
Browse files

ARM: 6331/1: ux500 cpu/SoC version macros v2



This patch adds support for checking if the digital baseband (DB)
System-on-Chip (aka "cpu) ASIC hardware version is 1.0, 1.1 or
2.0. We print the result in the bootlog, the functions are then
used for runtime decisions based on hardware version.

Signed-off-by: default avatarMattias Wallin <mattias.wallin@stericsson.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@stericsson.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 2bfc96a1
Loading
Loading
Loading
Loading
+82 −0
Original line number Diff line number Diff line
@@ -38,10 +38,12 @@ static struct platform_device *platform_devs[] __initdata = {
/* minimum static i/o mapping required to boot U8500 platforms */
static struct map_desc u8500_io_desc[] __initdata = {
	__IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
	__IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
	__IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
	__IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
	__IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
	__IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
	__MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M),
};

static struct map_desc u8500ed_io_desc[] __initdata = {
@@ -53,6 +55,69 @@ static struct map_desc u8500v1_io_desc[] __initdata = {
	__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
};

/*
 * Functions to differentiate between later ASICs
 * We look into the end of the ROM to locate the hardcoded ASIC ID.
 * This is only needed to differentiate between minor revisions and
 * process variants of an ASIC, the major revisions are encoded in
 * the cpuid.
 */
#define U8500_ASIC_ID_LOC_ED_V1	(U8500_BOOT_ROM_BASE + 0x1FFF4)
#define U8500_ASIC_ID_LOC_V2	(U8500_BOOT_ROM_BASE + 0x1DBF4)
#define U8500_ASIC_REV_ED	0x01
#define U8500_ASIC_REV_V10	0xA0
#define U8500_ASIC_REV_V11	0xA1
#define U8500_ASIC_REV_V20	0xB0

/**
 * struct db8500_asic_id - fields of the ASIC ID
 * @process: the manufacturing process, 0x40 is 40 nm
 *  0x00 is "standard"
 * @partnumber: hithereto 0x8500 for DB8500
 * @revision: version code in the series
 * This field definion is not formally defined but makes
 * sense.
 */
struct db8500_asic_id {
	u8 process;
	u16 partnumber;
	u8 revision;
};

/* This isn't going to change at runtime */
static struct db8500_asic_id db8500_id;

static void __init get_db8500_asic_id(void)
{
	u32 asicid;

	if (cpu_is_u8500v1() || cpu_is_u8500ed())
		asicid = readl(__io_address(U8500_ASIC_ID_LOC_ED_V1));
	else if (cpu_is_u8500v2())
		asicid = readl(__io_address(U8500_ASIC_ID_LOC_V2));
	else
		BUG();

	db8500_id.process = (asicid >> 24);
	db8500_id.partnumber = (asicid >> 16) & 0xFFFFU;
	db8500_id.revision = asicid & 0xFFU;
}

bool cpu_is_u8500v10(void)
{
	return (db8500_id.revision == U8500_ASIC_REV_V10);
}

bool cpu_is_u8500v11(void)
{
	return (db8500_id.revision == U8500_ASIC_REV_V11);
}

bool cpu_is_u8500v20(void)
{
	return (db8500_id.revision == U8500_ASIC_REV_V20);
}

void __init u8500_map_io(void)
{
	ux500_map_io();
@@ -63,6 +128,9 @@ void __init u8500_map_io(void)
		iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc));
	else
		iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc));

	/* Read out the ASIC ID as early as we can */
	get_db8500_asic_id();
}

/*
@@ -70,6 +138,20 @@ void __init u8500_map_io(void)
 */
void __init u8500_init_devices(void)
{
	/* Display some ASIC boilerplate */
	pr_info("DB8500: process: %02x, revision ID: 0x%02x\n",
		db8500_id.process, db8500_id.revision);
	if (cpu_is_u8500ed())
		pr_info("DB8500: Early Drop (ED)\n");
	else if (cpu_is_u8500v10())
		pr_info("DB8500: version 1.0\n");
	else if (cpu_is_u8500v11())
		pr_info("DB8500: version 1.1\n");
	else if (cpu_is_u8500v20())
		pr_info("DB8500: version 2.0\n");
	else
		pr_warning("ASIC: UNKNOWN SILICON VERSION!\n");

	ux500_init_devices();

	if (cpu_is_u8500ed())
+0 −2
Original line number Diff line number Diff line
@@ -30,8 +30,6 @@
#define U8500_ICN_BASE		0x81000000

#define U8500_BOOT_ROM_BASE	0x90000000
/* ASIC ID is at 0xff4 offset within this region */
#define U8500_ASIC_ID_BASE	0x9001F000

#define U8500_PER6_BASE		0xa03c0000
#define U8500_PER5_BASE		0xa03e0000
+21 −2
Original line number Diff line number Diff line
@@ -104,16 +104,35 @@ static inline bool cpu_is_u8500(void)
#endif
}

#define CPUID_DB8500ED	0x410fc090
#define CPUID_DB8500V1	0x411fc091
#define CPUID_DB8500V2	0x412fc091

static inline bool cpu_is_u8500ed(void)
{
	return cpu_is_u8500() && (read_cpuid_id() & 15) == 0;
	return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500ED);
}

static inline bool cpu_is_u8500v1(void)
{
	return cpu_is_u8500() && (read_cpuid_id() & 15) == 1;
	return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V1);
}

static inline bool cpu_is_u8500v2(void)
{
	return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V2);
}

#ifdef CONFIG_UX500_SOC_DB8500
bool cpu_is_u8500v10(void);
bool cpu_is_u8500v11(void);
bool cpu_is_u8500v20(void);
#else
static inline bool cpu_is_u8500v10(void) { return false; }
static inline bool cpu_is_u8500v11(void) { return false; }
static inline bool cpu_is_u8500v20(void) { return false; }
#endif

static inline bool cpu_is_u5500(void)
{
#ifdef CONFIG_UX500_SOC_DB5500
+7 −0
Original line number Diff line number Diff line
@@ -38,4 +38,11 @@ extern struct sys_timer ux500_timer;
	.type		= MT_DEVICE,		\
}

#define __MEM_DEV_DESC(x, sz)	{		\
	.virtual	= IO_ADDRESS(x),	\
	.pfn		= __phys_to_pfn(x),	\
	.length		= sz,			\
	.type		= MT_MEMORY,		\
}

#endif /*  __ASM_ARCH_SETUP_H */