From d8d959ad2b6c842888525e888707894d18b56d42 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 3 Apr 2013 10:12:16 +0200 Subject: ARM: mxs: add bootsource detection For now only the v1.2 i.MX28 silicon is supported. The actual information is read from a magic address within the internal SRAM. Signed-off-by: Marc Kleine-Budde Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/imx.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'arch/arm/mach-mxs/imx.c') diff --git a/arch/arm/mach-mxs/imx.c b/arch/arm/mach-mxs/imx.c index ab32f10351..cdf9275fb9 100644 --- a/arch/arm/mach-mxs/imx.c +++ b/arch/arm/mach-mxs/imx.c @@ -14,11 +14,15 @@ */ #include +#include #include #include #include #include + +#include #include +#include #define HW_RTC_PERSISTENT1 0x070 @@ -55,3 +59,98 @@ BAREBOX_CMD_START(dump_clocks) .usage = "show clock frequencies", BAREBOX_CMD_COMPLETE(empty_complete) BAREBOX_CMD_END + + +static int __silicon_revision = SILICON_REVISION_UNKNOWN; + +int silicon_revision_get(void) +{ + return __silicon_revision; +} + +void silicon_revision_set(const char *soc, int revision) +{ + __silicon_revision = revision; + + printf("detected %s revision %d.%d\n", soc, + (revision >> 4) & 0xf, revision & 0xf); +} + +#define HW_DIGCTL_CHIPID (0x8001c310) +#define HW_DIGCTL_CHIPID_MASK (0xffff << 16) +#define HW_DIGCTL_CHIPID_MX23 (0x3780 << 16) +#define HW_DIGCTL_CHIPID_MX28 (0x2800 << 16) + +static void mxs_silicon_revision(void) +{ + enum silicon_revision revision = SILICON_REVISION_UNKNOWN; + const char *product = "unknown"; + uint32_t reg; + uint8_t rev; + + reg = readl((void __iomem *)HW_DIGCTL_CHIPID); + rev = reg & 0xff; + + switch (reg & HW_DIGCTL_CHIPID_MASK) { + case HW_DIGCTL_CHIPID_MX23: + product = "i.MX23"; + switch (rev) { + case 0x0: revision = SILICON_REVISION_1_0; break; + case 0x1: revision = SILICON_REVISION_1_1; break; + case 0x2: revision = SILICON_REVISION_1_2; break; + case 0x3: revision = SILICON_REVISION_1_3; break; + case 0x4: revision = SILICON_REVISION_1_4; break; + } + case HW_DIGCTL_CHIPID_MX28: + product = "i.MX28"; + switch (rev) { + case 0x1: revision = SILICON_REVISION_1_2; break; + } + } + + silicon_revision_set(product, revision); +} + +#define MX28_REV_1_0_MODE (0x0001a7f0) +#define MX28_REV_1_2_MODE (0x00019bf0) + +static void mxs_boot_save_loc(void) +{ + enum bootsource src = BOOTSOURCE_UNKNOWN; + int instance = 0; + uint32_t mode = 0xff; + + if (cpu_is_mx23()) { + /* not implemented yet */ + } else if (cpu_is_mx28()) { + enum silicon_revision rev = silicon_revision_get(); + + if (rev == SILICON_REVISION_1_2) + mode = *(uint32_t *)MX28_REV_1_2_MODE; + else + mode = *(uint32_t *)MX28_REV_1_0_MODE; + } + + switch (mode & 0xf) { + case 0x0: src = BOOTSOURCE_USB; break; /* "USB" */ + case 0x1: src = BOOTSOURCE_I2C_EEPROM; break; /* "I2C, master" */ + case 0x3: instance = 1; /* fallthrough */ /* "SSP SPI #2, master, NOR" */ + case 0x2: src = BOOTSOURCE_SPI_NOR; break; /* "SSP SPI #1, master, NOR" */ + case 0x4: src = BOOTSOURCE_NAND; break; /* "NAND" */ + case 0x8: src = BOOTSOURCE_SPI_EEPROM; break; /* "SSP SPI #3, master, EEPROM" */ + case 0xa: instance = 1; /* fallthrough */ /* "SSP SD/MMC #1" */ + case 0x9: src = BOOTSOURCE_MMC; break; /* "SSP SD/MMC #0" */ + } + + bootsource_set(src); + bootsource_set_instance(instance); +} + +static int mxs_init(void) +{ + mxs_silicon_revision(); + mxs_boot_save_loc(); + + return 0; +} +postcore_initcall(mxs_init); -- cgit v1.2.3