summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/Kconfig5
-rw-r--r--arch/arm/mach-imx/Makefile1
-rw-r--r--arch/arm/mach-imx/boot.c435
-rw-r--r--arch/arm/mach-imx/esdctl.c144
-rw-r--r--arch/arm/mach-imx/imx.c52
-rw-r--r--arch/arm/mach-imx/imx51.c20
-rw-r--r--arch/arm/mach-imx/imx53.c4
-rw-r--r--arch/arm/mach-imx/imx6.c104
-rw-r--r--arch/arm/mach-imx/imx7.c19
-rw-r--r--arch/arm/mach-imx/include/mach/esdctl.h2
-rw-r--r--arch/arm/mach-imx/include/mach/generic.h3
-rw-r--r--arch/arm/mach-imx/include/mach/imx6-regs.h4
-rw-r--r--arch/arm/mach-imx/include/mach/imx6.h88
-rw-r--r--arch/arm/mach-imx/include/mach/reset-reason.h37
-rw-r--r--arch/arm/mach-imx/include/mach/vf610-ddrmc.h18
-rw-r--r--arch/arm/mach-imx/include/mach/vf610-regs.h5
-rw-r--r--arch/arm/mach-imx/include/mach/vf610.h51
-rw-r--r--arch/arm/mach-imx/vf610.c59
-rw-r--r--arch/arm/mach-imx/xload.c2
19 files changed, 794 insertions, 259 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 9052a94ea0..e6956acbdb 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -393,6 +393,11 @@ config MACH_CM_FX6
bool "CM FX6"
select ARCH_IMX6
+config MACH_ADVANTECH_ROM_742X
+ bool "Advantech ROM 742X"
+ select ARCH_IMX6
+ select ARM_USE_COMPRESSED_DTB
+
config MACH_WARP7
bool "NXP i.MX7: element 14 WaRP7 Board"
select ARCH_IMX7
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 8ec846ccef..160ed4b084 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o
CFLAGS_imx6.o := -march=armv7-a
lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
obj-$(CONFIG_ARCH_IMX7) += imx7.o
+obj-$(CONFIG_ARCH_VF610) += vf610.o
obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
obj-$(CONFIG_IMX_IIM) += iim.o
obj-$(CONFIG_IMX_OCOTP) += ocotp.o
diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c
index 72597f5e2d..22cf08e6ad 100644
--- a/arch/arm/mach-imx/boot.c
+++ b/arch/arm/mach-imx/boot.c
@@ -15,6 +15,7 @@
#include <bootsource.h>
#include <environment.h>
#include <init.h>
+#include <linux/bitfield.h>
#include <magicvar.h>
#include <io.h>
@@ -26,6 +27,21 @@
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
#include <mach/imx7-regs.h>
+#include <mach/vf610-regs.h>
+
+
+static void
+imx_boot_save_loc(void (*get_boot_source)(enum bootsource *, int *))
+{
+ enum bootsource src = BOOTSOURCE_UNKNOWN;
+ int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
+
+ get_boot_source(&src, &instance);
+
+ bootsource_set(src);
+ bootsource_set_instance(instance);
+}
+
/* [CTRL][TYPE] */
static const enum bootsource locations[4][4] = {
@@ -91,13 +107,7 @@ void imx25_get_boot_source(enum bootsource *src, int *instance)
void imx25_boot_save_loc(void)
{
- enum bootsource src = BOOTSOURCE_UNKNOWN;
- int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
-
- imx25_get_boot_source(&src, &instance);
-
- bootsource_set(src);
- bootsource_set_instance(instance);
+ imx_boot_save_loc(imx25_get_boot_source);
}
void imx35_get_boot_source(enum bootsource *src, int *instance)
@@ -112,13 +122,7 @@ void imx35_get_boot_source(enum bootsource *src, int *instance)
void imx35_boot_save_loc(void)
{
- enum bootsource src = BOOTSOURCE_UNKNOWN;
- int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
-
- imx35_get_boot_source(&src, &instance);
-
- bootsource_set(src);
- bootsource_set_instance(instance);
+ imx_boot_save_loc(imx35_get_boot_source);
}
#define IMX27_SYSCTRL_GPCR 0x18
@@ -159,13 +163,7 @@ void imx27_get_boot_source(enum bootsource *src, int *instance)
void imx27_boot_save_loc(void)
{
- enum bootsource src = BOOTSOURCE_UNKNOWN;
- int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
-
- imx27_get_boot_source(&src, &instance);
-
- bootsource_set(src);
- bootsource_set_instance(instance);
+ imx_boot_save_loc(imx27_get_boot_source);
}
#define IMX51_SRC_SBMR 0x4
@@ -203,36 +201,82 @@ void imx51_get_boot_source(enum bootsource *src, int *instance)
void imx51_boot_save_loc(void)
{
- enum bootsource src = BOOTSOURCE_UNKNOWN;
- int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
+ imx_boot_save_loc(imx51_get_boot_source);
+}
- imx51_get_boot_source(&src, &instance);
+#define IMX53_SRC_SBMR 0x4
+#define SRC_SBMR_BMOD GENMASK(25, 24)
+#define IMX53_BMOD_SERIAL 0b11
+
+#define __BOOT_CFG(n, m, l) GENMASK((m) + ((n) - 1) * 8, \
+ (l) + ((n) - 1) * 8)
+#define BOOT_CFG1(m, l) __BOOT_CFG(1, m, l)
+#define BOOT_CFG2(m, l) __BOOT_CFG(2, m, l)
+#define BOOT_CFG3(m, l) __BOOT_CFG(3, m, l)
+#define BOOT_CFG4(m, l) __BOOT_CFG(4, m, l)
+
+#define ___BOOT_CFG(n, i) __BOOT_CFG(n, i, i)
+#define __MAKE_BOOT_CFG_BITS(idx) \
+ enum { \
+ BOOT_CFG##idx##_0 = ___BOOT_CFG(idx, 0), \
+ BOOT_CFG##idx##_1 = ___BOOT_CFG(idx, 1), \
+ BOOT_CFG##idx##_2 = ___BOOT_CFG(idx, 2), \
+ BOOT_CFG##idx##_3 = ___BOOT_CFG(idx, 3), \
+ BOOT_CFG##idx##_4 = ___BOOT_CFG(idx, 4), \
+ BOOT_CFG##idx##_5 = ___BOOT_CFG(idx, 5), \
+ BOOT_CFG##idx##_6 = ___BOOT_CFG(idx, 6), \
+ BOOT_CFG##idx##_7 = ___BOOT_CFG(idx, 7), \
+ };
- bootsource_set(src);
- bootsource_set_instance(instance);
+__MAKE_BOOT_CFG_BITS(1)
+__MAKE_BOOT_CFG_BITS(2)
+__MAKE_BOOT_CFG_BITS(4)
+#undef __MAKE_BOOT_CFG
+#undef ___BOOT_CFG
+
+
+static unsigned int imx53_get_bmod(uint32_t r)
+{
+ return FIELD_GET(SRC_SBMR_BMOD, r);
+}
+
+static int imx53_bootsource_internal(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG1(7, 4), r);
+}
+
+static int imx53_port_select(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG3(5, 4), r);
+}
+
+static bool imx53_bootsource_nand(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG1_7, r);
+}
+
+static enum bootsource imx53_bootsource_serial_rom(uint32_t r)
+{
+ return BOOT_CFG1(r, 3) ? BOOTSOURCE_SPI : BOOTSOURCE_I2C;
}
-#define IMX53_SRC_SBMR 0x4
void imx53_get_boot_source(enum bootsource *src, int *instance)
{
void __iomem *src_base = IOMEM(MX53_SRC_BASE_ADDR);
uint32_t cfg1 = readl(src_base + IMX53_SRC_SBMR);
- if (((cfg1 >> 24) & 0x3) == 0x3) {
+ if (imx53_get_bmod(cfg1) == IMX53_BMOD_SERIAL) {
*src = BOOTSOURCE_USB;
*instance = 0;
return;
}
- switch ((cfg1 & 0xff) >> 4) {
+ switch (imx53_bootsource_internal(cfg1)) {
case 2:
*src = BOOTSOURCE_HD;
break;
case 3:
- if (cfg1 & (1 << 3))
- *src = BOOTSOURCE_SPI;
- else
- *src = BOOTSOURCE_I2C;
+ *src = imx53_bootsource_serial_rom(cfg1);
break;
case 4:
case 5:
@@ -241,18 +285,16 @@ void imx53_get_boot_source(enum bootsource *src, int *instance)
*src = BOOTSOURCE_MMC;
break;
default:
+ if (imx53_bootsource_nand(cfg1))
+ *src = BOOTSOURCE_NAND;
break;
}
- if (cfg1 & (1 << 7))
- *src = BOOTSOURCE_NAND;
-
-
switch (*src) {
case BOOTSOURCE_MMC:
case BOOTSOURCE_SPI:
case BOOTSOURCE_I2C:
- *instance = (cfg1 >> 20) & 0x3;
+ *instance = imx53_port_select(cfg1);
break;
default:
*instance = 0;
@@ -273,123 +315,206 @@ void imx53_boot_save_loc(void)
#define IMX6_SRC_SBMR1 0x04
#define IMX6_SRC_SBMR2 0x1c
+#define IMX6_BMOD_SERIAL 0b01
+#define IMX6_BMOD_RESERVED 0b11
+#define IMX6_BMOD_FUSES 0b00
+#define BT_FUSE_SEL BIT(4)
+
+static bool imx6_bootsource_reserved(uint32_t sbmr2)
+{
+ return imx53_get_bmod(sbmr2) == IMX6_BMOD_RESERVED;
+}
+
+static bool imx6_bootsource_serial(uint32_t sbmr2)
+{
+ return imx53_get_bmod(sbmr2) == IMX6_BMOD_SERIAL ||
+ /*
+ * If boot from fuses is selected and fuses are not
+ * programmed by setting BT_FUSE_SEL, ROM code will
+ * fallback to serial mode
+ */
+ (imx53_get_bmod(sbmr2) == IMX6_BMOD_FUSES &&
+ !(sbmr2 & BT_FUSE_SEL));
+}
+
+static int __imx6_bootsource_serial_rom(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG4(2, 0), r);
+}
+
+/*
+ * Serial ROM bootsource on i.MX6 are as follows:
+ *
+ * 000 - ECSPI-1
+ * 001 - ECSPI-2
+ * 010 - ECSPI-3
+ * 011 - ECSPI-4
+ * 100 - ECSPI-5
+ * 101 - I2C1
+ * 110 - I2C2
+ * 111 - I2C3
+ *
+ * There's no single bit that would tell us we are booting from I2C or
+ * SPI, so we just have to compare the "source" agains the value for
+ * I2C1 for both: calculating bootsource and boot instance.
+ */
+#define IMX6_BOOTSOURCE_SERIAL_ROM_I2C1 0b101
+
+static enum bootsource imx6_bootsource_serial_rom(uint32_t sbmr)
+{
+ const int source = __imx6_bootsource_serial_rom(sbmr);
+
+ return source < IMX6_BOOTSOURCE_SERIAL_ROM_I2C1 ?
+ BOOTSOURCE_SPI_NOR : BOOTSOURCE_I2C;
+}
+
+static int imx6_boot_instance_serial_rom(uint32_t sbmr)
+{
+ const int source = __imx6_bootsource_serial_rom(sbmr);
+
+ if (source < IMX6_BOOTSOURCE_SERIAL_ROM_I2C1)
+ return source;
+
+ return source - IMX6_BOOTSOURCE_SERIAL_ROM_I2C1;
+}
+
+static int imx6_boot_instance_mmc(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG2(4, 3), r);
+}
void imx6_get_boot_source(enum bootsource *src, int *instance)
{
void __iomem *src_base = IOMEM(MX6_SRC_BASE_ADDR);
uint32_t sbmr1 = readl(src_base + IMX6_SRC_SBMR1);
uint32_t sbmr2 = readl(src_base + IMX6_SRC_SBMR2);
- uint32_t boot_cfg_4_2_0;
- int boot_mode;
- /* BMOD[1:0] */
- boot_mode = (sbmr2 >> 24) & 0x3;
+ if (imx6_bootsource_reserved(sbmr2))
+ return;
- switch (boot_mode) {
- case 0: /* Fuses, fall through */
- case 2: /* internal boot */
- goto internal_boot;
- case 1: /* Serial Downloader */
+ if (imx6_bootsource_serial(sbmr2)) {
*src = BOOTSOURCE_SERIAL;
- break;
- case 3: /* reserved */
- break;
- };
-
- return;
-
-internal_boot:
+ return;
+ }
- /* BOOT_CFG1[7:4] */
- switch ((sbmr1 >> 4) & 0xf) {
+ switch (imx53_bootsource_internal(sbmr1)) {
case 2:
*src = BOOTSOURCE_HD;
break;
case 3:
- /* BOOT_CFG4[2:0] */
- boot_cfg_4_2_0 = (sbmr1 >> 24) & 0x7;
-
- if (boot_cfg_4_2_0 > 4) {
- *src = BOOTSOURCE_I2C;
- *instance = boot_cfg_4_2_0 - 5;
- } else {
- *src = BOOTSOURCE_SPI;
- *instance = boot_cfg_4_2_0;
- }
+ *src = imx6_bootsource_serial_rom(sbmr1);
+ *instance = imx6_boot_instance_serial_rom(sbmr1);
break;
case 4:
case 5:
case 6:
case 7:
*src = BOOTSOURCE_MMC;
-
- /* BOOT_CFG2[4:3] */
- *instance = (sbmr1 >> 11) & 0x3;
+ *instance = imx6_boot_instance_mmc(sbmr1);
break;
default:
+ if (imx53_bootsource_nand(sbmr1))
+ *src = BOOTSOURCE_NAND;
break;
}
-
- /* BOOT_CFG1[7:0] */
- if (sbmr1 & (1 << 7))
- *src = BOOTSOURCE_NAND;
-
- return;
}
void imx6_boot_save_loc(void)
{
- enum bootsource src = BOOTSOURCE_UNKNOWN;
- int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
-
- imx6_get_boot_source(&src, &instance);
-
- bootsource_set(src);
- bootsource_set_instance(instance);
+ imx_boot_save_loc(imx6_get_boot_source);
}
#define IMX7_SRC_SBMR1 0x58
#define IMX7_SRC_SBMR2 0x70
+/*
+ * Re-defined to match the naming in reference manual
+ */
+#define BOOT_CFG(m, l) BOOT_CFG1(m, l)
+
+#define IMX_BOOT_SW_INFO_POINTER_ADDR 0x000001E8
+#define IMX_BOOT_SW_INFO_BDT_SD 0x1
+
+static unsigned int imx7_bootsource_internal(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG(15, 12), r);
+}
+
+static int imx7_boot_instance_spi_nor(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG(11, 9), r);
+}
+
+static int imx7_boot_instance_mmc(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG(11, 10), r);
+}
+
+struct imx_boot_sw_info {
+ uint8_t reserved_1;
+ uint8_t boot_device_instance;
+ uint8_t boot_device_type;
+ uint8_t reserved_2;
+ uint32_t frequency_hz[4]; /* Various frequencies (ARM, AXI,
+ * DDR, etc.). Not used */
+ uint32_t reserved_3[3];
+} __packed;
+
void imx7_get_boot_source(enum bootsource *src, int *instance)
{
void __iomem *src_base = IOMEM(MX7_SRC_BASE_ADDR);
uint32_t sbmr1 = readl(src_base + IMX7_SRC_SBMR1);
uint32_t sbmr2 = readl(src_base + IMX7_SRC_SBMR2);
- int boot_mode;
- /* BMOD[1:0] */
- boot_mode = (sbmr2 >> 24) & 0x3;
-
- switch (boot_mode) {
- case 0: /* Fuses, fall through */
- case 2: /* internal boot */
- goto internal_boot;
- case 1: /* Serial Downloader */
- *src = BOOTSOURCE_SERIAL;
- break;
- case 3: /* reserved */
- break;
- };
+ if (imx6_bootsource_reserved(sbmr2))
+ return;
- return;
+ if (imx6_bootsource_serial(sbmr2)) {
+ /*
+ * On i.MX7 ROM code will try to bood from uSDHC1
+ * before entering serial mode. It doesn't seem to be
+ * reflected in the contents of SBMR1 in any way when
+ * that happens, so we check "Boot_SW_Info" structure
+ * (per 6.6.14 Boot information for software) to see
+ * if that really happened.
+ *
+ * FIXME: This behaviour can be inhibited by
+ * DISABLE_SDMMC_MFG, but location of that fuse
+ * doesn't seem to be documented anywhere. Once that
+ * is known it should be taken into account here.
+ */
+ const struct imx_boot_sw_info *info;
+
+ info = (const void *)readl(IMX_BOOT_SW_INFO_POINTER_ADDR);
+
+ if (info->boot_device_type == IMX_BOOT_SW_INFO_BDT_SD) {
+ *src = BOOTSOURCE_MMC;
+ /*
+ * We are expecting to only ever boot from
+ * uSDHC1 here
+ */
+ WARN_ON(*instance = info->boot_device_instance);
+ return;
+ }
-internal_boot:
+ *src = BOOTSOURCE_SERIAL;
+ return;
+ }
- switch ((sbmr1 >> 12) & 0xf) {
+ switch (imx7_bootsource_internal(sbmr1)) {
case 1:
case 2:
*src = BOOTSOURCE_MMC;
- *instance = (sbmr1 >> 10 & 0x3);
+ *instance = imx7_boot_instance_mmc(sbmr1);
break;
case 3:
*src = BOOTSOURCE_NAND;
break;
- case 4:
+ case 6:
*src = BOOTSOURCE_SPI_NOR,
- *instance = (sbmr1 >> 9 & 0x7);
+ *instance = imx7_boot_instance_spi_nor(sbmr1);
break;
- case 6:
+ case 4:
*src = BOOTSOURCE_SPI; /* Really: qspi */
break;
case 5:
@@ -398,21 +523,103 @@ internal_boot:
default:
break;
}
+}
- /* BOOT_CFG1[7:0] */
- if (sbmr1 & (1 << 7))
- *src = BOOTSOURCE_NAND;
+void imx7_boot_save_loc(void)
+{
+ imx_boot_save_loc(imx7_get_boot_source);
+}
- return;
+static int vf610_boot_instance_spi(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG1_1, r);
}
-void imx7_boot_save_loc(void)
+static int vf610_boot_instance_nor(uint32_t r)
{
- enum bootsource src = BOOTSOURCE_UNKNOWN;
- int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
+ return FIELD_GET(BOOT_CFG1_3, r);
+}
+
+/*
+ * Vybrid's Serial ROM boot sources (BOOT_CFG4[2:0]) are as follows:
+ *
+ * 000 - SPI0
+ * 001 - SPI1
+ * 010 - SPI2
+ * 011 - SPI3
+ * 100 - I2C0
+ * 101 - I2C1
+ * 110 - I2C2
+ * 111 - I2C3
+ *
+ * Which we can neatly divide in two halves and use MSb to detect if
+ * bootsource is I2C or SPI EEPROM and 2 LSbs directly as boot
+ * insance.
+ */
+static enum bootsource vf610_bootsource_serial_rom(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG4_2, r) ? BOOTSOURCE_I2C : BOOTSOURCE_SPI_NOR;
+}
- imx7_get_boot_source(&src, &instance);
+static int vf610_boot_instance_serial_rom(uint32_t r)
+{
+ return __imx6_bootsource_serial_rom(r) & 0b11;
+}
- bootsource_set(src);
- bootsource_set_instance(instance);
+static int vf610_boot_instance_can(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG1_0, r);
+}
+
+static int vf610_boot_instance_mmc(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG2_3, r);
+}
+
+void vf610_get_boot_source(enum bootsource *src, int *instance)
+{
+ void __iomem *src_base = IOMEM(VF610_SRC_BASE_ADDR);
+ uint32_t sbmr1 = readl(src_base + IMX6_SRC_SBMR1);
+ uint32_t sbmr2 = readl(src_base + IMX6_SRC_SBMR2);
+
+ if (imx6_bootsource_reserved(sbmr2))
+ return;
+
+ if (imx6_bootsource_serial(sbmr2)) {
+ *src = BOOTSOURCE_SERIAL;
+ return;
+ }
+
+ switch (imx53_bootsource_internal(sbmr1)) {
+ case 0:
+ *src = BOOTSOURCE_SPI; /* Really: qspi */
+ *instance = vf610_boot_instance_spi(sbmr1);
+ break;
+ case 1:
+ *src = BOOTSOURCE_NOR;
+ *instance = vf610_boot_instance_nor(sbmr1);
+ break;
+ case 2:
+ *src = vf610_bootsource_serial_rom(sbmr1);
+ *instance = vf610_boot_instance_serial_rom(sbmr1);
+ break;
+ case 3:
+ *src = BOOTSOURCE_CAN;
+ *instance = vf610_boot_instance_can(sbmr1);
+ break;
+ case 6:
+ case 7:
+ *src = BOOTSOURCE_MMC;
+ *instance = vf610_boot_instance_mmc(sbmr1);
+ break;
+ default:
+ if (imx53_bootsource_nand(sbmr1))
+ *src = BOOTSOURCE_NAND;
+ break;
+ }
+}
+
+void vf610_boot_save_loc(void)
+{
+ imx_boot_save_loc(vf610_get_boot_source);
}
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 1eebc77b63..c1680d5ff8 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -37,6 +37,7 @@
#include <mach/imx51-regs.h>
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
+#include <mach/vf610-ddrmc.h>
struct imx_esdctl_data {
unsigned long base0;
@@ -75,12 +76,9 @@ static inline unsigned long imx_v1_sdram_size(void __iomem *esdctlbase, int num)
if (ctlval & (1 << 17))
width = 4;
- size = (1 << cols) * (1 << rows) * banks * width;
+ size = memory_sdram_size(cols, rows, banks, width);
- if (size > SZ_64M)
- size = SZ_64M;
-
- return size;
+ return min_t(unsigned long, size, SZ_64M);
}
/*
@@ -103,12 +101,9 @@ static inline unsigned long imx_v2_sdram_size(void __iomem *esdctlbase, int num)
if ((ctlval & ESDCTL0_DSIZ_MASK) == ESDCTL0_DSIZ_31_0)
width = 4;
- size = (1 << cols) * (1 << rows) * banks * width;
-
- if (size > SZ_256M)
- size = SZ_256M;
+ size = memory_sdram_size(cols, rows, banks, width);
- return size;
+ return min_t(unsigned long, size, SZ_256M);
}
/*
@@ -120,13 +115,10 @@ static inline unsigned long imx_v3_sdram_size(void __iomem *esdctlbase, int num)
size = imx_v2_sdram_size(esdctlbase, num);
- if (readl(esdctlbase + IMX_ESDMISC) & (1 << 6))
+ if (readl(esdctlbase + IMX_ESDMISC) & ESDMISC_DDR2_8_BANK)
size *= 2;
- if (size > SZ_256M)
- size = SZ_256M;
-
- return size;
+ return min_t(unsigned long, size, SZ_256M);
}
/*
@@ -136,7 +128,6 @@ static inline unsigned long imx_v4_sdram_size(void __iomem *esdctlbase, int cs)
{
u32 ctlval = readl(esdctlbase + ESDCTL_V4_ESDCTL0);
u32 esdmisc = readl(esdctlbase + ESDCTL_V4_ESDMISC);
- unsigned long size;
int rows, cols, width = 2, banks = 8;
if (cs == 0 && !(ctlval & ESDCTL_V4_ESDCTLx_SDE0))
@@ -162,20 +153,17 @@ static inline unsigned long imx_v4_sdram_size(void __iomem *esdctlbase, int cs)
if (esdmisc & ESDCTL_V4_ESDMISC_BANKS_4)
banks = 4;
- size = (1 << cols) * (1 << rows) * banks * width;
-
- return size;
+ return memory_sdram_size(cols, rows, banks, width);
}
/*
* MMDC - found on i.MX6
*/
-static inline u64 imx6_mmdc_sdram_size(void __iomem *mmdcbase, int cs)
+static inline u64 __imx6_mmdc_sdram_size(void __iomem *mmdcbase, int cs)
{
u32 ctlval = readl(mmdcbase + MDCTL);
u32 mdmisc = readl(mmdcbase + MDMISC);
- u64 size;
int rows, cols, width = 2, banks = 8;
if (cs == 0 && !(ctlval & MMDCx_MDCTL_SDE0))
@@ -201,9 +189,7 @@ static inline u64 imx6_mmdc_sdram_size(void __iomem *mmdcbase, int cs)
if (mdmisc & MMDCx_MDMISC_DDR_4_BANKS)
banks = 4;
- size = (u64)(1 << cols) * (1 << rows) * banks * width;
-
- return size;
+ return memory_sdram_size(cols, rows, banks, width);
}
static void add_mem(unsigned long base0, unsigned long size0,
@@ -286,7 +272,7 @@ static void imx_esdctl_v4_add_mem(void *esdctlbase, struct imx_esdctl_data *data
*/
#define IMX6_MAX_SDRAM_SIZE 0xF0000000
-static void imx6_mmdc_add_mem(void *mmdcbase, struct imx_esdctl_data *data)
+static inline resource_size_t imx6_mmdc_sdram_size(void __iomem *mmdcbase)
{
/*
* It is possible to have a configuration in which both chip
@@ -296,14 +282,41 @@ static void imx6_mmdc_add_mem(void *mmdcbase, struct imx_esdctl_data *data)
* IMX6_MAX_SDRAM_SIZE bytes of memory available.
*/
- u64 size_cs0 = imx6_mmdc_sdram_size(mmdcbase, 0);
- u64 size_cs1 = imx6_mmdc_sdram_size(mmdcbase, 1);
+ u64 size_cs0 = __imx6_mmdc_sdram_size(mmdcbase, 0);
+ u64 size_cs1 = __imx6_mmdc_sdram_size(mmdcbase, 1);
u64 total = size_cs0 + size_cs1;
resource_size_t size = min(total, (u64)IMX6_MAX_SDRAM_SIZE);
+ return size;
+}
+
+static void imx6_mmdc_add_mem(void *mmdcbase, struct imx_esdctl_data *data)
+{
+ arm_add_mem_device("ram0", data->base0,
+ imx6_mmdc_sdram_size(mmdcbase));
+}
+
+static inline resource_size_t vf610_ddrmc_sdram_size(void __iomem *ddrmc)
+{
+ const u32 cr01 = readl(ddrmc + DDRMC_CR(1));
+ const u32 cr73 = readl(ddrmc + DDRMC_CR(73));
+ const u32 cr78 = readl(ddrmc + DDRMC_CR(78));
+
+ unsigned int rows, cols, width, banks;
+
+ rows = DDRMC_CR01_MAX_ROW_REG(cr01) - DDRMC_CR73_ROW_DIFF(cr73);
+ cols = DDRMC_CR01_MAX_COL_REG(cr01) - DDRMC_CR73_COL_DIFF(cr73);
+ banks = 1 << (3 - DDRMC_CR73_BANK_DIFF(cr73));
+ width = (cr78 & DDRMC_CR78_REDUC) ? sizeof(u8) : sizeof(u16);
+
+ return memory_sdram_size(cols, rows, banks, width);
+}
+
+static void vf610_ddrmc_add_mem(void *mmdcbase, struct imx_esdctl_data *data)
+{
arm_add_mem_device("ram0", data->base0,
- size);
+ vf610_ddrmc_sdram_size(mmdcbase));
}
static int imx_esdctl_probe(struct device_d *dev)
@@ -373,15 +386,20 @@ static __maybe_unused struct imx_esdctl_data imx53_data = {
};
static __maybe_unused struct imx_esdctl_data imx6q_data = {
- .base0 = MX6_MMDC_PORT0_BASE_ADDR,
+ .base0 = MX6_MMDC_PORT01_BASE_ADDR,
.add_mem = imx6_mmdc_add_mem,
};
static __maybe_unused struct imx_esdctl_data imx6ul_data = {
- .base0 = 0x80000000,
+ .base0 = MX6_MMDC_PORT0_BASE_ADDR,
.add_mem = imx6_mmdc_add_mem,
};
+static __maybe_unused struct imx_esdctl_data vf610_data = {
+ .base0 = VF610_RAM_BASE_ADDR,
+ .add_mem = vf610_ddrmc_add_mem,
+};
+
static struct platform_device_id imx_esdctl_ids[] = {
#ifdef CONFIG_ARCH_IMX1
{
@@ -441,6 +459,9 @@ static __maybe_unused struct of_device_id imx_esdctl_dt_ids[] = {
.compatible = "fsl,imx6q-mmdc",
.data = &imx6q_data
}, {
+ .compatible = "fsl,vf610-ddrmc",
+ .data = &vf610_data
+ }, {
/* sentinel */
}
};
@@ -498,9 +519,9 @@ void __noreturn imx1_barebox_entry(void *boarddata)
unsigned long base, size;
upper_or_coalesced_range(MX1_CSD0_BASE_ADDR,
- imx_v1_sdram_size((void *)MX1_SDRAMC_BASE_ADDR, 0),
+ imx_v1_sdram_size(IOMEM(MX1_SDRAMC_BASE_ADDR), 0),
MX1_CSD1_BASE_ADDR,
- imx_v1_sdram_size((void *)MX1_SDRAMC_BASE_ADDR, 1),
+ imx_v1_sdram_size(IOMEM(MX1_SDRAMC_BASE_ADDR), 1),
&base, &size);
barebox_arm_entry(base, size, boarddata);
@@ -511,9 +532,9 @@ void __noreturn imx25_barebox_entry(void *boarddata)
unsigned long base, size;
upper_or_coalesced_range(MX25_CSD0_BASE_ADDR,
- imx_v2_sdram_size((void *)MX25_ESDCTL_BASE_ADDR, 0),
+ imx_v2_sdram_size(IOMEM(MX25_ESDCTL_BASE_ADDR), 0),
MX25_CSD1_BASE_ADDR,
- imx_v2_sdram_size((void *)MX25_ESDCTL_BASE_ADDR, 1),
+ imx_v2_sdram_size(IOMEM(MX25_ESDCTL_BASE_ADDR), 1),
&base, &size);
barebox_arm_entry(base, size, boarddata);
@@ -523,12 +544,12 @@ void __noreturn imx27_barebox_entry(void *boarddata)
{
unsigned long base, size;
- imx_esdctl_v2_disable_default((void *)MX27_ESDCTL_BASE_ADDR);
+ imx_esdctl_v2_disable_default(IOMEM(MX27_ESDCTL_BASE_ADDR));
upper_or_coalesced_range(MX27_CSD0_BASE_ADDR,
- imx_v2_sdram_size((void *)MX27_ESDCTL_BASE_ADDR, 0),
+ imx_v2_sdram_size(IOMEM(MX27_ESDCTL_BASE_ADDR), 0),
MX27_CSD1_BASE_ADDR,
- imx_v2_sdram_size((void *)MX27_ESDCTL_BASE_ADDR, 1),
+ imx_v2_sdram_size(IOMEM(MX27_ESDCTL_BASE_ADDR), 1),
&base, &size);
barebox_arm_entry(base, size, boarddata);
@@ -538,12 +559,12 @@ void __noreturn imx31_barebox_entry(void *boarddata)
{
unsigned long base, size;
- imx_esdctl_v2_disable_default((void *)MX31_ESDCTL_BASE_ADDR);
+ imx_esdctl_v2_disable_default(IOMEM(MX31_ESDCTL_BASE_ADDR));
upper_or_coalesced_range(MX31_CSD0_BASE_ADDR,
- imx_v2_sdram_size((void *)MX31_ESDCTL_BASE_ADDR, 0),
+ imx_v2_sdram_size(IOMEM(MX31_ESDCTL_BASE_ADDR), 0),
MX31_CSD1_BASE_ADDR,
- imx_v2_sdram_size((void *)MX31_ESDCTL_BASE_ADDR, 1),
+ imx_v2_sdram_size(IOMEM(MX31_ESDCTL_BASE_ADDR), 1),
&base, &size);
barebox_arm_entry(base, size, boarddata);
@@ -553,12 +574,12 @@ void __noreturn imx35_barebox_entry(void *boarddata)
{
unsigned long base, size;
- imx_esdctl_v2_disable_default((void *)MX35_ESDCTL_BASE_ADDR);
+ imx_esdctl_v2_disable_default(IOMEM(MX35_ESDCTL_BASE_ADDR));
upper_or_coalesced_range(MX35_CSD0_BASE_ADDR,
- imx_v2_sdram_size((void *)MX35_ESDCTL_BASE_ADDR, 0),
+ imx_v2_sdram_size(IOMEM(MX35_ESDCTL_BASE_ADDR), 0),
MX35_CSD1_BASE_ADDR,
- imx_v2_sdram_size((void *)MX35_ESDCTL_BASE_ADDR, 1),
+ imx_v2_sdram_size(IOMEM(MX35_ESDCTL_BASE_ADDR), 1),
&base, &size);
barebox_arm_entry(base, size, boarddata);
@@ -569,9 +590,9 @@ void __noreturn imx51_barebox_entry(void *boarddata)
unsigned long base, size;
upper_or_coalesced_range(MX51_CSD0_BASE_ADDR,
- imx_v3_sdram_size((void *)MX51_ESDCTL_BASE_ADDR, 0),
+ imx_v3_sdram_size(IOMEM(MX51_ESDCTL_BASE_ADDR), 0),
MX51_CSD1_BASE_ADDR,
- imx_v3_sdram_size((void *)MX51_ESDCTL_BASE_ADDR, 1),
+ imx_v3_sdram_size(IOMEM(MX51_ESDCTL_BASE_ADDR), 1),
&base, &size);
barebox_arm_entry(base, size, boarddata);
@@ -582,32 +603,35 @@ void __noreturn imx53_barebox_entry(void *boarddata)
unsigned long base, size;
upper_or_coalesced_range(MX53_CSD0_BASE_ADDR,
- imx_v4_sdram_size((void *)MX53_ESDCTL_BASE_ADDR, 0),
+ imx_v4_sdram_size(IOMEM(MX53_ESDCTL_BASE_ADDR), 0),
MX53_CSD1_BASE_ADDR,
- imx_v4_sdram_size((void *)MX53_ESDCTL_BASE_ADDR, 1),
+ imx_v4_sdram_size(IOMEM(MX53_ESDCTL_BASE_ADDR), 1),
&base, &size);
barebox_arm_entry(base, size, boarddata);
}
-void __noreturn imx6q_barebox_entry(void *boarddata)
+static void __noreturn
+imx6_barebox_entry(unsigned long membase, void *boarddata)
{
- u64 size_cs0 = imx6_mmdc_sdram_size((void *)MX6_MMDC_P0_BASE_ADDR, 0);
- u64 size_cs1 = imx6_mmdc_sdram_size((void *)MX6_MMDC_P0_BASE_ADDR, 1);
- u64 total = size_cs0 + size_cs1;
-
- resource_size_t size = min(total, (u64)IMX6_MAX_SDRAM_SIZE);
+ barebox_arm_entry(membase,
+ imx6_mmdc_sdram_size(IOMEM(MX6_MMDC_P0_BASE_ADDR)),
+ boarddata);
+}
- barebox_arm_entry(0x10000000, size, boarddata);
+void __noreturn imx6q_barebox_entry(void *boarddata)
+{
+ imx6_barebox_entry(MX6_MMDC_PORT01_BASE_ADDR, boarddata);
}
void __noreturn imx6ul_barebox_entry(void *boarddata)
{
- u64 size_cs0 = imx6_mmdc_sdram_size((void *)MX6_MMDC_P0_BASE_ADDR, 0);
- u64 size_cs1 = imx6_mmdc_sdram_size((void *)MX6_MMDC_P0_BASE_ADDR, 1);
- u64 total = size_cs0 + size_cs1;
-
- resource_size_t size = min(total, (u64)IMX6_MAX_SDRAM_SIZE);
+ imx6_barebox_entry(MX6_MMDC_PORT0_BASE_ADDR, boarddata);
+}
- barebox_arm_entry(0x80000000, size, boarddata);
+void __noreturn vf610_barebox_entry(void *boarddata)
+{
+ barebox_arm_entry(VF610_RAM_BASE_ADDR,
+ vf610_ddrmc_sdram_size(IOMEM(VF610_DDR_BASE_ADDR)),
+ boarddata);
}
diff --git a/arch/arm/mach-imx/imx.c b/arch/arm/mach-imx/imx.c
index 9400105c66..1b4c1b3df1 100644
--- a/arch/arm/mach-imx/imx.c
+++ b/arch/arm/mach-imx/imx.c
@@ -14,8 +14,10 @@
#include <common.h>
#include <of.h>
#include <init.h>
+#include <io.h>
#include <mach/revision.h>
#include <mach/generic.h>
+#include <mach/reset-reason.h>
static int __imx_silicon_revision = IMX_CHIP_REV_UNKNOWN;
@@ -28,7 +30,10 @@ void imx_set_silicon_revision(const char *soc, int revision)
{
__imx_silicon_revision = revision;
- pr_info("detected %s revision %d.%d\n", soc,
+ if (revision == IMX_CHIP_REV_UNKNOWN)
+ pr_info("detected %s revision unknown\n", soc);
+ else
+ pr_info("detected %s revision %d.%d\n", soc,
(revision >> 4) & 0xf,
revision & 0xf);
}
@@ -114,7 +119,7 @@ static int imx_init(void)
else if (cpu_is_mx7())
ret = imx7_init();
else if (cpu_is_vf610())
- ret = 0;
+ ret = vf610_init();
else
return -EINVAL;
@@ -147,3 +152,46 @@ static int imx_init(void)
return ret;
}
postcore_initcall(imx_init);
+
+const struct imx_reset_reason imx_reset_reasons[] = {
+ { IMX_SRC_SRSR_IPP_RESET, RESET_POR, 0 },
+ { IMX_SRC_SRSR_WDOG1_RESET, RESET_WDG, 0 },
+ { IMX_SRC_SRSR_JTAG_RESET, RESET_JTAG, 0 },
+ { IMX_SRC_SRSR_JTAG_SW_RESET, RESET_JTAG, 0 },
+ { IMX_SRC_SRSR_WARM_BOOT, RESET_RST, 0 },
+ { /* sentinel */ }
+};
+
+void imx_set_reset_reason(void __iomem *srsr,
+ const struct imx_reset_reason *reasons)
+{
+ enum reset_src_type type = RESET_UKWN;
+ const u32 reg = readl(srsr);
+ int i, instance = 0;
+
+ /*
+ * SRSR register captures ALL reset event that occured since
+ * POR, so we need to clear it to make sure we only caputre
+ * the latest one.
+ */
+ writel(reg, srsr);
+
+ for (i = 0; reasons[i].mask; i++) {
+ if (reg & reasons[i].mask) {
+ type = reasons[i].type;
+ instance = reasons[i].instance;
+ break;
+ }
+ }
+
+ /*
+ * Report this with above default priority in order to make
+ * sure we'll always override info from watchdog driver.
+ */
+ reset_source_set_priority(type,
+ RESET_SOURCE_DEFAULT_PRIORITY + 1);
+ reset_source_set_instance(type, instance);
+
+ pr_info("i.MX reset reason %s (SRSR: 0x%08x)\n",
+ reset_source_name(), reg);
+}
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index ffe6a7c651..ec8cdd868b 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -21,6 +21,7 @@
#include <mach/revision.h>
#include <mach/clock-imx51_53.h>
#include <mach/generic.h>
+#include <mach/reset-reason.h>
#define IIM_SREV 0x24
@@ -43,7 +44,7 @@ static int imx51_silicon_revision(void)
static void imx51_ipu_mipi_setup(void)
{
- void __iomem *hsc_addr = (void __iomem *)MX51_MIPI_HSC_BASE_ADDR;
+ void __iomem *hsc_addr = IOMEM(MX51_MIPI_HSC_BASE_ADDR);
u32 val;
/* setup MIPI module to legacy mode */
@@ -57,7 +58,10 @@ static void imx51_ipu_mipi_setup(void)
int imx51_init(void)
{
+ void __iomem *src = IOMEM(MX51_SRC_BASE_ADDR);
+
imx_set_silicon_revision("i.MX51", imx51_silicon_revision());
+ imx_set_reset_reason(src + IMX_SRC_SRSR, imx_reset_reasons);
imx51_boot_save_loc();
add_generic_device("imx51-esdctl", 0, NULL, MX51_ESDCTL_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
imx51_ipu_mipi_setup();
@@ -97,7 +101,7 @@ int imx51_devices_init(void)
*/
static void imx51_setup_pll800_bug(void)
{
- void __iomem *base = (void *)MX51_PLL1_BASE_ADDR;
+ void __iomem *base = IOMEM(MX51_PLL1_BASE_ADDR);
u32 dp_config;
volatile int i;
@@ -132,7 +136,7 @@ static void imx51_setup_pll800_bug(void)
void imx51_init_lowlevel(unsigned int cpufreq_mhz)
{
- void __iomem *ccm = (void __iomem *)MX51_CCM_BASE_ADDR;
+ void __iomem *ccm = IOMEM(MX51_CCM_BASE_ADDR);
u32 r;
int rev = imx51_silicon_revision();
@@ -167,30 +171,30 @@ void imx51_init_lowlevel(unsigned int cpufreq_mhz)
switch (cpufreq_mhz) {
case 600:
- imx5_setup_pll_600((void __iomem *)MX51_PLL1_BASE_ADDR);
+ imx5_setup_pll_600(IOMEM(MX51_PLL1_BASE_ADDR));
break;
default:
/* Default maximum 800MHz */
if (rev <= IMX_CHIP_REV_3_0)
imx51_setup_pll800_bug();
else
- imx5_setup_pll_800((void __iomem *)MX51_PLL1_BASE_ADDR);
+ imx5_setup_pll_800(IOMEM(MX51_PLL1_BASE_ADDR));
break;
}
- imx5_setup_pll_665((void __iomem *)MX51_PLL3_BASE_ADDR);
+ imx5_setup_pll_665(IOMEM(MX51_PLL3_BASE_ADDR));
/* Switch peripheral to PLL 3 */
writel(0x000010C0, ccm + MX5_CCM_CBCMR);
writel(0x13239145, ccm + MX5_CCM_CBCDR);
- imx5_setup_pll_665((void __iomem *)MX51_PLL2_BASE_ADDR);
+ imx5_setup_pll_665(IOMEM(MX51_PLL2_BASE_ADDR));
/* Switch peripheral to PLL2 */
writel(0x19239145, ccm + MX5_CCM_CBCDR);
writel(0x000020C0, ccm + MX5_CCM_CBCMR);
- imx5_setup_pll_216((void __iomem *)MX51_PLL3_BASE_ADDR);
+ imx5_setup_pll_216(IOMEM(MX51_PLL3_BASE_ADDR));
/* Set the platform clock dividers */
writel(0x00000125, MX51_ARM_BASE_ADDR + 0x14);
diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index 2758f1bbcf..56f1bda75e 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -21,6 +21,7 @@
#include <mach/revision.h>
#include <mach/clock-imx51_53.h>
#include <mach/generic.h>
+#include <mach/reset-reason.h>
#define SI_REV 0x48
@@ -52,7 +53,10 @@ static int imx53_silicon_revision(void)
int imx53_init(void)
{
+ void __iomem *src = IOMEM(MX53_SRC_BASE_ADDR);
+
imx53_silicon_revision();
+ imx_set_reset_reason(src + IMX_SRC_SRSR, imx_reset_reasons);
imx53_boot_save_loc();
add_generic_device("imx53-esdctl", 0, NULL, MX53_ESDCTL_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index 14a1cba5a4..eaf9f2e413 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -16,9 +16,11 @@
#include <io.h>
#include <linux/sizes.h>
#include <mfd/imx6q-iomuxc-gpr.h>
+#include <mach/clock-imx6.h>
#include <mach/imx6.h>
#include <mach/generic.h>
#include <mach/revision.h>
+#include <mach/reset-reason.h>
#include <mach/imx6-anadig.h>
#include <mach/imx6-regs.h>
#include <mach/generic.h>
@@ -44,6 +46,11 @@ static void imx6_init_lowlevel(void)
void __iomem *aips2 = (void *)MX6_AIPS2_ON_BASE_ADDR;
bool is_imx6q = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6Q;
bool is_imx6d = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6D;
+ uint32_t val_480;
+ uint32_t val_528;
+ uint32_t periph_sel_1;
+ uint32_t periph_sel_2;
+ uint32_t reg;
/*
* Set all MPROTx to be non-bufferable, trusted for R/W,
@@ -68,32 +75,38 @@ static void imx6_init_lowlevel(void)
/* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
* to make sure PFD is working right, otherwise, PFDs may
* not output clock after reset, MX6DL and MX6SL have added 396M pfd
- * workaround in ROM code, as bus clock need it
+ * workaround in ROM code, as bus clock need it.
+ * Don't reset PLL2 PFD0 / PLL2 PFD2 if is's used by periph_clk.
*/
if (is_imx6q || is_imx6d) {
- writel(BM_ANADIG_PFD_480_PFD3_CLKGATE |
- BM_ANADIG_PFD_480_PFD2_CLKGATE |
- BM_ANADIG_PFD_480_PFD1_CLKGATE |
- BM_ANADIG_PFD_480_PFD0_CLKGATE,
- MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_SET);
- writel(BM_ANADIG_PFD_528_PFD3_CLKGATE |
- BM_ANADIG_PFD_528_PFD2_CLKGATE |
- BM_ANADIG_PFD_528_PFD1_CLKGATE |
- BM_ANADIG_PFD_528_PFD0_CLKGATE,
- MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_SET);
-
- writel(BM_ANADIG_PFD_480_PFD3_CLKGATE |
- BM_ANADIG_PFD_480_PFD2_CLKGATE |
- BM_ANADIG_PFD_480_PFD1_CLKGATE |
- BM_ANADIG_PFD_480_PFD0_CLKGATE,
- MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_CLR);
- writel(BM_ANADIG_PFD_528_PFD3_CLKGATE |
- BM_ANADIG_PFD_528_PFD2_CLKGATE |
- BM_ANADIG_PFD_528_PFD1_CLKGATE |
- BM_ANADIG_PFD_528_PFD0_CLKGATE,
- MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_CLR);
- }
+ val_480 = BM_ANADIG_PFD_480_PFD3_CLKGATE |
+ BM_ANADIG_PFD_480_PFD2_CLKGATE |
+ BM_ANADIG_PFD_480_PFD1_CLKGATE |
+ BM_ANADIG_PFD_480_PFD0_CLKGATE;
+
+ val_528 = BM_ANADIG_PFD_528_PFD3_CLKGATE |
+ BM_ANADIG_PFD_528_PFD1_CLKGATE;
+
+ reg = readl(MXC_CCM_CBCMR);
+ periph_sel_1 = (reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
+ >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
+
+ periph_sel_2 = (reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)
+ >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET;
+
+ if ((periph_sel_1 != 0x2) && (periph_sel_2 != 0x2))
+ val_528 |= BM_ANADIG_PFD_528_PFD0_CLKGATE;
+
+ if ((periph_sel_1 != 0x1) && (periph_sel_2 != 0x1)
+ && (periph_sel_1 != 0x3) && (periph_sel_2 != 0x3))
+ val_528 |= BM_ANADIG_PFD_528_PFD2_CLKGATE;
+
+ writel(val_480, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_SET);
+ writel(val_528, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_SET);
+ writel(val_480, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_CLR);
+ writel(val_528, MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_CLR);
+ }
}
static void imx6_setup_ipu_qos(void)
@@ -147,10 +160,37 @@ static void imx6ul_enet_clk_init(void)
writel(val, gprbase + IOMUXC_GPR1);
}
+int imx6_cpu_type(void)
+{
+ static int cpu_type = -1;
+
+ if (!cpu_is_mx6())
+ return 0;
+
+ if (cpu_type < 0)
+ cpu_type = __imx6_cpu_type();
+
+ return cpu_type;
+}
+
+int imx6_cpu_revision(void)
+{
+ static int soc_revision = -1;
+
+ if (!cpu_is_mx6())
+ return 0;
+
+ if (soc_revision < 0)
+ soc_revision = __imx6_cpu_revision();
+
+ return soc_revision;
+}
+
int imx6_init(void)
{
const char *cputypestr;
u32 mx6_silicon_revision;
+ void __iomem *src = IOMEM(MX6_SRC_BASE_ADDR);
imx6_init_lowlevel();
@@ -160,16 +200,16 @@ int imx6_init(void)
switch (imx6_cpu_type()) {
case IMX6_CPUTYPE_IMX6Q:
- if (mx6_silicon_revision >= IMX_CHIP_REV_2_0)
- cputypestr = "i.MX6 Quad Plus";
- else
- cputypestr = "i.MX6 Quad";
+ cputypestr = "i.MX6 Quad";
+ break;
+ case IMX6_CPUTYPE_IMX6QP:
+ cputypestr = "i.MX6 Quad Plus";
break;
case IMX6_CPUTYPE_IMX6D:
- if (mx6_silicon_revision >= IMX_CHIP_REV_2_0)
- cputypestr = "i.MX6 Dual Plus";
- else
- cputypestr = "i.MX6 Dual";
+ cputypestr = "i.MX6 Dual";
+ break;
+ case IMX6_CPUTYPE_IMX6DP:
+ cputypestr = "i.MX6 Dual Plus";
break;
case IMX6_CPUTYPE_IMX6DL:
cputypestr = "i.MX6 DualLite";
@@ -195,7 +235,7 @@ int imx6_init(void)
}
imx_set_silicon_revision(cputypestr, mx6_silicon_revision);
-
+ imx_set_reset_reason(src + IMX_SRC_SRSR, imx_reset_reasons);
imx6_setup_ipu_qos();
imx6ul_enet_clk_init();
diff --git a/arch/arm/mach-imx/imx7.c b/arch/arm/mach-imx/imx7.c
index 4eef99c872..e49baf6f77 100644
--- a/arch/arm/mach-imx/imx7.c
+++ b/arch/arm/mach-imx/imx7.c
@@ -19,6 +19,7 @@
#include <mach/imx7.h>
#include <mach/generic.h>
#include <mach/revision.h>
+#include <mach/reset-reason.h>
#include <mach/imx7-regs.h>
void imx7_init_lowlevel(void)
@@ -167,10 +168,21 @@ static struct psci_ops imx7_psci_ops = {
.cpu_off = imx7_cpu_off,
};
+static const struct imx_reset_reason imx7_reset_reasons[] = {
+ { IMX_SRC_SRSR_IPP_RESET, RESET_POR, 0 },
+ { IMX_SRC_SRSR_WDOG1_RESET, RESET_WDG, 0 },
+ { IMX_SRC_SRSR_JTAG_RESET, RESET_JTAG, 0 },
+ { IMX_SRC_SRSR_JTAG_SW_RESET, RESET_JTAG, 0 },
+ { IMX_SRC_SRSR_WDOG3_RESET, RESET_WDG, 1 },
+ { IMX_SRC_SRSR_WDOG4_RESET, RESET_WDG, 2 },
+ { IMX_SRC_SRSR_TEMPSENSE_RESET, RESET_THERM, 0 },
+ { /* sentinel */ }
+};
+
int imx7_init(void)
{
const char *cputypestr;
- u32 imx7_silicon_revision;
+ void __iomem *src = IOMEM(MX7_SRC_BASE_ADDR);
imx7_init_lowlevel();
@@ -180,8 +192,6 @@ int imx7_init(void)
imx7_boot_save_loc();
- imx7_silicon_revision = imx7_cpu_revision();
-
psci_set_ops(&imx7_psci_ops);
switch (imx7_cpu_type()) {
@@ -196,7 +206,8 @@ int imx7_init(void)
break;
}
- imx_set_silicon_revision(cputypestr, imx7_silicon_revision);
+ imx_set_silicon_revision(cputypestr, imx7_cpu_revision());
+ imx_set_reset_reason(src + IMX7_SRC_SRSR, imx7_reset_reasons);
return 0;
}
diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h
index 66dcc8974c..117e2bbad5 100644
--- a/arch/arm/mach-imx/include/mach/esdctl.h
+++ b/arch/arm/mach-imx/include/mach/esdctl.h
@@ -48,6 +48,7 @@
#define ESDMISC_MDDR_MDIS 0x00000010
#define ESDMISC_LHD 0x00000020
#define ESDMISC_SDRAMRDY 0x80000000
+#define ESDMISC_DDR2_8_BANK BIT(6)
#define ESDCFGx_tXP_MASK 0x00600000
#define ESDCFGx_tXP_1 0x00000000
@@ -137,6 +138,7 @@ void __noreturn imx51_barebox_entry(void *boarddata);
void __noreturn imx53_barebox_entry(void *boarddata);
void __noreturn imx6q_barebox_entry(void *boarddata);
void __noreturn imx6ul_barebox_entry(void *boarddata);
+void __noreturn vf610_barebox_entry(void *boarddata);
void imx_esdctl_disable(void);
#endif
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index f68dc875b0..ad9d9cb022 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -15,6 +15,7 @@ void imx51_boot_save_loc(void);
void imx53_boot_save_loc(void);
void imx6_boot_save_loc(void);
void imx7_boot_save_loc(void);
+void vf610_boot_save_loc(void);
void imx25_get_boot_source(enum bootsource *src, int *instance);
void imx35_get_boot_source(enum bootsource *src, int *instance);
@@ -22,6 +23,7 @@ void imx51_get_boot_source(enum bootsource *src, int *instance);
void imx53_get_boot_source(enum bootsource *src, int *instance);
void imx6_get_boot_source(enum bootsource *src, int *instance);
void imx7_get_boot_source(enum bootsource *src, int *instance);
+void vf610_get_boot_source(enum bootsource *src, int *instance);
int imx1_init(void);
int imx21_init(void);
@@ -34,6 +36,7 @@ int imx51_init(void);
int imx53_init(void);
int imx6_init(void);
int imx7_init(void);
+int vf610_init(void);
int imx1_devices_init(void);
int imx21_devices_init(void);
diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h
index ac2aa2109f..1ba22b5bc6 100644
--- a/arch/arm/mach-imx/include/mach/imx6-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx6-regs.h
@@ -117,6 +117,8 @@
#define MX6_SATA_BASE_ADDR 0x02200000
-#define MX6_MMDC_PORT0_BASE_ADDR 0x10000000
+#define MX6_MMDC_PORT01_BASE_ADDR 0x10000000
+#define MX6_MMDC_PORT0_BASE_ADDR 0x80000000
+
#endif /* __MACH_IMX6_REGS_H */
diff --git a/arch/arm/mach-imx/include/mach/imx6.h b/arch/arm/mach-imx/include/mach/imx6.h
index 6b08e6a521..5701bd480c 100644
--- a/arch/arm/mach-imx/include/mach/imx6.h
+++ b/arch/arm/mach-imx/include/mach/imx6.h
@@ -16,7 +16,9 @@ void __noreturn imx6_pm_stby_poweroff(void);
#define IMX6_CPUTYPE_IMX6DL 0x261
#define IMX6_CPUTYPE_IMX6SX 0x462
#define IMX6_CPUTYPE_IMX6D 0x263
+#define IMX6_CPUTYPE_IMX6DP 0x1263
#define IMX6_CPUTYPE_IMX6Q 0x463
+#define IMX6_CPUTYPE_IMX6QP 0x1463
#define IMX6_CPUTYPE_IMX6UL 0x164
#define IMX6_CPUTYPE_IMX6ULL 0x165
@@ -33,36 +35,51 @@ static inline int scu_get_core_count(void)
return (ncores & 0x03) + 1;
}
-static inline int __imx6_cpu_type(void)
+#define SI_REV_CPUTYPE(s) (((s) >> 16) & 0xff)
+#define SI_REV_MAJOR(s) (((s) >> 8) & 0xf)
+#define SI_REV_MINOR(s) ((s) & 0xf)
+
+static inline uint32_t __imx6_read_si_rev(void)
{
- uint32_t val;
-
- val = readl(MX6_ANATOP_BASE_ADDR + IMX6_ANATOP_SI_REV);
- val = (val >> 16) & 0xff;
- /* non-MX6-standard SI_REV reg offset for MX6SL */
- if (IS_ENABLED(CONFIG_ARCH_IMX6SL) &&
- val < (IMX6_CPUTYPE_IMX6S & 0xff)) {
- uint32_t tmp;
- tmp = readl(MX6_ANATOP_BASE_ADDR + IMX6SL_ANATOP_SI_REV);
- tmp = (tmp >> 16) & 0xff;
- if ((IMX6_CPUTYPE_IMX6SL & 0xff) == tmp)
- /* intentionally skip scu_get_core_count() for MX6SL */
- return IMX6_CPUTYPE_IMX6SL;
- }
+ uint32_t si_rev;
+ uint32_t cpu_type;
+
+ si_rev = readl(MX6_ANATOP_BASE_ADDR + IMX6_ANATOP_SI_REV);
+ cpu_type = SI_REV_CPUTYPE(si_rev);
- val |= scu_get_core_count() << 8;
+ if (cpu_type >= 0x61 && cpu_type <= 0x65)
+ return si_rev;
- return val;
+ /* try non-MX6-standard SI_REV reg offset for MX6SL */
+ si_rev = readl(MX6_ANATOP_BASE_ADDR + IMX6SL_ANATOP_SI_REV);
+ cpu_type = SI_REV_CPUTYPE(si_rev);
+
+ if (si_rev == 0x60)
+ return si_rev;
+
+ return 0;
}
-static inline int imx6_cpu_type(void)
+static inline int __imx6_cpu_type(void)
{
- if (!cpu_is_mx6())
- return 0;
+ uint32_t si_rev = __imx6_read_si_rev();
+ uint32_t cpu_type = SI_REV_CPUTYPE(si_rev);
+
+ /* intentionally skip scu_get_core_count() for MX6SL */
+ if (cpu_type == IMX6_CPUTYPE_IMX6SL)
+ return IMX6_CPUTYPE_IMX6SL;
- return __imx6_cpu_type();
+ cpu_type |= scu_get_core_count() << 8;
+
+ if ((cpu_type == IMX6_CPUTYPE_IMX6D || cpu_type == IMX6_CPUTYPE_IMX6Q) &&
+ SI_REV_MAJOR(si_rev) >= 1)
+ cpu_type |= 0x1000;
+
+ return cpu_type;
}
+int imx6_cpu_type(void);
+
#define DEFINE_MX6_CPU_TYPE(str, type) \
static inline int cpu_mx6_is_##str(void) \
{ \
@@ -76,10 +93,19 @@ static inline int imx6_cpu_type(void)
return cpu_mx6_is_##str(); \
}
+/*
+ * Below are defined:
+ *
+ * cpu_is_mx6s(), cpu_is_mx6dl(), cpu_is_mx6q(), cpu_is_mx6qp(), cpu_is_mx6d(),
+ * cpu_is_mx6dp(), cpu_is_mx6sx(), cpu_is_mx6sl(), cpu_is_mx6ul(),
+ * cpu_is_mx6ull()
+ */
DEFINE_MX6_CPU_TYPE(mx6s, IMX6_CPUTYPE_IMX6S);
DEFINE_MX6_CPU_TYPE(mx6dl, IMX6_CPUTYPE_IMX6DL);
DEFINE_MX6_CPU_TYPE(mx6q, IMX6_CPUTYPE_IMX6Q);
+DEFINE_MX6_CPU_TYPE(mx6qp, IMX6_CPUTYPE_IMX6QP);
DEFINE_MX6_CPU_TYPE(mx6d, IMX6_CPUTYPE_IMX6D);
+DEFINE_MX6_CPU_TYPE(mx6dp, IMX6_CPUTYPE_IMX6DP);
DEFINE_MX6_CPU_TYPE(mx6sx, IMX6_CPUTYPE_IMX6SX);
DEFINE_MX6_CPU_TYPE(mx6sl, IMX6_CPUTYPE_IMX6SL);
DEFINE_MX6_CPU_TYPE(mx6ul, IMX6_CPUTYPE_IMX6UL);
@@ -87,27 +113,15 @@ DEFINE_MX6_CPU_TYPE(mx6ull, IMX6_CPUTYPE_IMX6ULL);
static inline int __imx6_cpu_revision(void)
{
- uint32_t rev;
- uint32_t si_rev_offset = IMX6_ANATOP_SI_REV;
+ uint32_t si_rev = __imx6_read_si_rev();
u8 major_part, minor_part;
- if (IS_ENABLED(CONFIG_ARCH_IMX6SL) && cpu_mx6_is_mx6sl())
- si_rev_offset = IMX6SL_ANATOP_SI_REV;
-
- rev = readl(MX6_ANATOP_BASE_ADDR + si_rev_offset);
-
- major_part = (rev >> 8) & 0xf;
- minor_part = rev & 0xf;
+ major_part = (si_rev >> 8) & 0xf;
+ minor_part = si_rev & 0xf;
return ((major_part + 1) << 4) | minor_part;
}
-static inline int imx6_cpu_revision(void)
-{
- if (!cpu_is_mx6())
- return 0;
-
- return __imx6_cpu_revision();
-}
+int imx6_cpu_revision(void);
#endif /* __MACH_IMX6_H */
diff --git a/arch/arm/mach-imx/include/mach/reset-reason.h b/arch/arm/mach-imx/include/mach/reset-reason.h
new file mode 100644
index 0000000000..0f644a8c1d
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/reset-reason.h
@@ -0,0 +1,37 @@
+#ifndef __MACH_RESET_REASON_H__
+#define __MACH_RESET_REASON_H__
+
+#include <reset_source.h>
+
+#define IMX_SRC_SRSR_IPP_RESET BIT(0)
+#define IMX_SRC_SRSR_CSU_RESET BIT(2)
+#define IMX_SRC_SRSR_IPP_USER_RESET BIT(3)
+#define IMX_SRC_SRSR_WDOG1_RESET BIT(4)
+#define IMX_SRC_SRSR_JTAG_RESET BIT(5)
+#define IMX_SRC_SRSR_JTAG_SW_RESET BIT(6)
+#define IMX_SRC_SRSR_WDOG3_RESET BIT(7)
+#define IMX_SRC_SRSR_WDOG4_RESET BIT(8)
+#define IMX_SRC_SRSR_TEMPSENSE_RESET BIT(9)
+#define IMX_SRC_SRSR_WARM_BOOT BIT(16)
+
+#define IMX_SRC_SRSR 0x008
+#define IMX7_SRC_SRSR 0x05c
+
+#define VF610_SRC_SRSR_SW_RST BIT(18)
+#define VF610_SRC_SRSR_RESETB BIT(7)
+#define VF610_SRC_SRSR_JTAG_RST BIT(5)
+#define VF610_SRC_SRSR_WDOG_M4 BIT(4)
+#define VF610_SRC_SRSR_WDOG_A5 BIT(3)
+#define VF610_SRC_SRSR_POR_RST BIT(0)
+
+struct imx_reset_reason {
+ uint32_t mask;
+ enum reset_src_type type;
+ int instance;
+};
+
+void imx_set_reset_reason(void __iomem *, const struct imx_reset_reason *);
+
+extern const struct imx_reset_reason imx_reset_reasons[];
+
+#endif /* __MACH_RESET_REASON_H__ */
diff --git a/arch/arm/mach-imx/include/mach/vf610-ddrmc.h b/arch/arm/mach-imx/include/mach/vf610-ddrmc.h
new file mode 100644
index 0000000000..07feb036e5
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/vf610-ddrmc.h
@@ -0,0 +1,18 @@
+#ifndef __MACH_DDRMC_H
+#define __MACH_DDRMC_H
+
+#include <mach/vf610-regs.h>
+
+
+#define DDRMC_CR(x) ((x) * 4)
+
+#define DDRMC_CR01_MAX_COL_REG(reg) (((reg) >> 8) & 0b01111)
+#define DDRMC_CR01_MAX_ROW_REG(reg) (((reg) >> 0) & 0b11111)
+#define DDRMC_CR73_COL_DIFF(reg) (((reg) >> 16) & 0b00111)
+#define DDRMC_CR73_ROW_DIFF(reg) (((reg) >> 8) & 0b00011)
+#define DDRMC_CR73_BANK_DIFF(reg) (((reg) >> 0) & 0b00011)
+
+#define DDRMC_CR78_REDUC BIT(8)
+
+
+#endif /* __MACH_MMDC_H */
diff --git a/arch/arm/mach-imx/include/mach/vf610-regs.h b/arch/arm/mach-imx/include/mach/vf610-regs.h
index 8be220b68c..416b457aff 100644
--- a/arch/arm/mach-imx/include/mach/vf610-regs.h
+++ b/arch/arm/mach-imx/include/mach/vf610-regs.h
@@ -13,6 +13,8 @@
#define VF610_AIPS0_BASE_ADDR 0x40000000
#define VF610_AIPS1_BASE_ADDR 0x40080000
+#define VF610_RAM_BASE_ADDR 0x80000000
+
/* AIPS 0 */
#define VF610_MSCM_BASE_ADDR (VF610_AIPS0_BASE_ADDR + 0x00001000)
#define VF610_MSCM_IR_BASE_ADDR (VF610_AIPS0_BASE_ADDR + 0x00001800)
@@ -107,4 +109,7 @@
#define VF610_MSCM_IRSPRC_CP0_EN 1
#define VF610_MSCM_IRSPRC_NUM 112
+#define VF610_MSCM_CPxCOUNT 0x00c
+#define VF610_MSCM_CPxCFG1 0x014
+
#endif
diff --git a/arch/arm/mach-imx/include/mach/vf610.h b/arch/arm/mach-imx/include/mach/vf610.h
new file mode 100644
index 0000000000..6d00d2e457
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/vf610.h
@@ -0,0 +1,51 @@
+#ifndef __MACH_VF610_H
+#define __MACH_VF610_H
+
+#include <io.h>
+#include <mach/generic.h>
+#include <mach/vf610-regs.h>
+#include <mach/revision.h>
+
+#define VF610_CPUTYPE_VFx10 0x010
+
+#define VF610_CPUTYPE_VF610 0x610
+#define VF610_CPUTYPE_VF600 0x600
+#define VF610_CPUTYPE_VF510 0x510
+#define VF610_CPUTYPE_VF500 0x500
+
+#define VF610_ROM_VERSION_OFFSET 0x80
+
+static inline int __vf610_cpu_type(void)
+{
+ void __iomem *mscm = IOMEM(VF610_MSCM_BASE_ADDR);
+ const u32 cpxcount = readl(mscm + VF610_MSCM_CPxCOUNT);
+ const u32 cpxcfg1 = readl(mscm + VF610_MSCM_CPxCFG1);
+ int cpu_type;
+
+ cpu_type = cpxcount ? VF610_CPUTYPE_VF600 : VF610_CPUTYPE_VF500;
+
+ return cpxcfg1 ? cpu_type | VF610_CPUTYPE_VFx10 : cpu_type;
+}
+
+static inline int vf610_cpu_type(void)
+{
+ if (!cpu_is_vf610())
+ return 0;
+
+ return __vf610_cpu_type();
+}
+
+static inline int vf610_cpu_revision(void)
+{
+ if (!cpu_is_vf610())
+ return IMX_CHIP_REV_UNKNOWN;
+
+ /*
+ * There doesn't seem to be a documented way of retreiving
+ * silicon revision on VFxxx cpus, so we just report Mask ROM
+ * version instead
+ */
+ return readl(VF610_ROM_VERSION_OFFSET) & 0xff;
+}
+
+#endif
diff --git a/arch/arm/mach-imx/vf610.c b/arch/arm/mach-imx/vf610.c
new file mode 100644
index 0000000000..c535716c10
--- /dev/null
+++ b/arch/arm/mach-imx/vf610.c
@@ -0,0 +1,59 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <init.h>
+#include <common.h>
+#include <io.h>
+#include <linux/sizes.h>
+#include <mach/generic.h>
+#include <mach/revision.h>
+#include <mach/vf610.h>
+#include <mach/reset-reason.h>
+
+static const struct imx_reset_reason vf610_reset_reasons[] = {
+ { VF610_SRC_SRSR_POR_RST, RESET_POR, 0 },
+ { VF610_SRC_SRSR_WDOG_A5, RESET_WDG, 0 },
+ { VF610_SRC_SRSR_WDOG_M4, RESET_WDG, 1 },
+ { VF610_SRC_SRSR_JTAG_RST, RESET_JTAG, 0 },
+ { VF610_SRC_SRSR_RESETB, RESET_EXT, 0 },
+ { VF610_SRC_SRSR_SW_RST, RESET_RST, 0 },
+ { /* sentinel */ }
+};
+
+int vf610_init(void)
+{
+ const char *cputypestr;
+ void __iomem *src = IOMEM(VF610_SRC_BASE_ADDR);
+
+ switch (vf610_cpu_type()) {
+ case VF610_CPUTYPE_VF610:
+ cputypestr = "VF610";
+ break;
+ case VF610_CPUTYPE_VF600:
+ cputypestr = "VF600";
+ break;
+ case VF610_CPUTYPE_VF510:
+ cputypestr = "VF510";
+ break;
+ case VF610_CPUTYPE_VF500:
+ cputypestr = "VF500";
+ break;
+ default:
+ cputypestr = "unknown VFxxx";
+ break;
+ }
+
+ imx_set_silicon_revision(cputypestr, vf610_cpu_revision());
+ imx_set_reset_reason(src + IMX_SRC_SRSR, vf610_reset_reasons);
+ return 0;
+}
diff --git a/arch/arm/mach-imx/xload.c b/arch/arm/mach-imx/xload.c
index 16d56ab288..921e9ade20 100644
--- a/arch/arm/mach-imx/xload.c
+++ b/arch/arm/mach-imx/xload.c
@@ -24,7 +24,7 @@ static __noreturn int imx_xload(void)
pr_info("booting from MMC\n");
buf = bootstrap_read_disk("disk0.0", "fat");
break;
- case BOOTSOURCE_SPI:
+ case BOOTSOURCE_SPI_NOR:
pr_info("booting from SPI\n");
buf = bootstrap_read_devfs("dataflash0", false,
SZ_256K, SZ_1M, SZ_1M);