summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/boot.c')
-rw-r--r--arch/arm/mach-imx/boot.c119
1 files changed, 87 insertions, 32 deletions
diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c
index 16a377341c..3fea22d05f 100644
--- a/arch/arm/mach-imx/boot.c
+++ b/arch/arm/mach-imx/boot.c
@@ -8,21 +8,21 @@
#include <magicvar.h>
#include <io.h>
-#include <mach/clock-imx6.h>
-#include <mach/generic.h>
-#include <mach/imx25-regs.h>
-#include <mach/imx27-regs.h>
-#include <mach/imx35-regs.h>
-#include <mach/imx51-regs.h>
-#include <mach/imx53-regs.h>
-#include <mach/imx6-regs.h>
-#include <mach/imx7-regs.h>
-#include <mach/imx8mm-regs.h>
-#include <mach/imx8mp-regs.h>
-#include <mach/imx8mq-regs.h>
-#include <mach/vf610-regs.h>
-#include <mach/imx8mq.h>
-#include <mach/imx6.h>
+#include <mach/imx/clock-imx6.h>
+#include <mach/imx/generic.h>
+#include <mach/imx/imx25-regs.h>
+#include <mach/imx/imx27-regs.h>
+#include <mach/imx/imx35-regs.h>
+#include <mach/imx/imx51-regs.h>
+#include <mach/imx/imx53-regs.h>
+#include <mach/imx/imx6-regs.h>
+#include <mach/imx/imx7-regs.h>
+#include <mach/imx/imx8mm-regs.h>
+#include <mach/imx/imx8mp-regs.h>
+#include <mach/imx/imx8mq-regs.h>
+#include <mach/imx/vf610-regs.h>
+#include <mach/imx/imx8mq.h>
+#include <mach/imx/imx6.h>
#include <soc/fsl/fsl_udc.h>
@@ -34,8 +34,7 @@ imx_boot_save_loc(void (*get_boot_source)(enum bootsource *, int *))
get_boot_source(&src, &instance);
- bootsource_set(src);
- bootsource_set_instance(instance);
+ bootsource_set(src, instance);
}
@@ -203,7 +202,8 @@ void imx51_boot_save_loc(void)
}
#define IMX53_SRC_SBMR 0x4
-#define SRC_SBMR_BMOD GENMASK(25, 24)
+#define IMX53_SRC_SBMR_BMOD GENMASK(25, 24)
+#define IMX8MP_SRC_SBMR_BMOD GENMASK(27, 24)
#define IMX53_BMOD_SERIAL 0b11
#define __BOOT_CFG(n, m, l) GENMASK((m) + ((n) - 1) * 8, \
@@ -235,7 +235,17 @@ __MAKE_BOOT_CFG_BITS(4)
static unsigned int imx53_get_bmod(uint32_t r)
{
- return FIELD_GET(SRC_SBMR_BMOD, r);
+ return FIELD_GET(IMX53_SRC_SBMR_BMOD, r);
+}
+
+static unsigned int imx8mp_get_bmod(uint32_t r)
+{
+ return FIELD_GET(IMX8MP_SRC_SBMR_BMOD, r);
+}
+
+static unsigned int imx8mm_get_bcfg(uint32_t r)
+{
+ return FIELD_GET(BOOT_CFG2(6, 4), r);
}
static int imx53_bootsource_internal(uint32_t r)
@@ -309,8 +319,7 @@ void imx53_boot_save_loc(void)
imx53_get_boot_source(&src, &instance);
- bootsource_set(src);
- bootsource_set_instance(instance);
+ bootsource_set(src, instance);
}
#define IMX6_SRC_SBMR1 0x04
@@ -319,6 +328,9 @@ void imx53_boot_save_loc(void)
#define IMX6_SRC_GPR10 0x44
#define IMX6_BMOD_SERIAL 0b01
#define IMX6_BMOD_RESERVED 0b11
+#define IMX8MM_BCFG_FSPI 0b100
+#define IMX8MP_BMOD_FUSES 0b0000
+#define IMX8MP_BMOD_SERIAL 0b0001
#define IMX6_BMOD_FUSES 0b00
#define BT_FUSE_SEL BIT(4)
#define GPR10_BOOT_FROM_GPR9 BIT(28)
@@ -340,6 +352,23 @@ static bool imx6_bootsource_serial(uint32_t sbmr2)
!(sbmr2 & BT_FUSE_SEL));
}
+static bool imx8mp_bootsource_serial(uint32_t sbmr2)
+{
+ return imx8mp_get_bmod(sbmr2) == IMX8MP_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
+ */
+ (imx8mp_get_bmod(sbmr2) == IMX8MP_BMOD_FUSES &&
+ !(sbmr2 & BT_FUSE_SEL));
+}
+
+static bool imx8mm_bootsource_qspi(uint32_t sbmr1)
+{
+ return imx8mm_get_bcfg(sbmr1) == IMX8MM_BCFG_FSPI;
+}
+
static bool imx6_bootsource_serial_forced(uint32_t bootmode)
{
if (cpu_mx6_is_mx6ul() || cpu_mx6_is_mx6ull())
@@ -499,11 +528,6 @@ static void __imx7_get_boot_source(enum bootsource *src, int *instance,
{
const struct imx_boot_sw_info *info;
- if (imx6_bootsource_serial(sbmr2)) {
- *src = BOOTSOURCE_SERIAL;
- return;
- }
-
info = (const void *)(unsigned long)
readl(boot_sw_info_pointer_addr);
@@ -522,6 +546,7 @@ static void __imx7_get_boot_source(enum bootsource *src, int *instance,
break;
case 4:
*src = BOOTSOURCE_SPI; /* Really: qspi */
+ *instance = info->boot_device_instance;
break;
case 5:
*src = BOOTSOURCE_NOR;
@@ -541,6 +566,11 @@ void imx7_get_boot_source(enum bootsource *src, int *instance)
void __iomem *src_base = IOMEM(MX7_SRC_BASE_ADDR);
uint32_t sbmr2 = readl(src_base + 0x70);
+ if (imx6_bootsource_serial(sbmr2)) {
+ *src = BOOTSOURCE_SERIAL;
+ return;
+ }
+
__imx7_get_boot_source(src, instance, IMX7_BOOT_SW_INFO_POINTER_ADDR,
sbmr2);
}
@@ -656,6 +686,11 @@ void imx8mq_get_boot_source(enum bootsource *src, int *instance)
IMX8M_BOOT_SW_INFO_POINTER_ADDR_A0 :
IMX8M_BOOT_SW_INFO_POINTER_ADDR_B0;
+ if (imx6_bootsource_serial(sbmr2)) {
+ *src = BOOTSOURCE_SERIAL;
+ return;
+ }
+
__imx7_get_boot_source(src, instance, addr, sbmr2);
}
@@ -668,11 +703,26 @@ void imx8mm_get_boot_source(enum bootsource *src, int *instance)
{
unsigned long addr;
void __iomem *src_base = IOMEM(MX8MM_SRC_BASE_ADDR);
+ uint32_t sbmr1 = readl(src_base + 0x58);
uint32_t sbmr2 = readl(src_base + 0x70);
+ if (imx6_bootsource_serial(sbmr2)) {
+ *src = BOOTSOURCE_SERIAL;
+ return;
+ }
+
addr = IMX8M_BOOT_SW_INFO_POINTER_ADDR_A0;
__imx7_get_boot_source(src, instance, addr, sbmr2);
+
+ if (*src != BOOTSOURCE_UNKNOWN)
+ return;
+
+ if (imx8mm_bootsource_qspi(sbmr1)) {
+ *src = BOOTSOURCE_SPI; /* Really: qspi */
+ *instance = 0;
+ return;
+ }
}
void imx8mm_boot_save_loc(void)
@@ -680,18 +730,17 @@ void imx8mm_boot_save_loc(void)
imx_boot_save_loc(imx8mm_get_boot_source);
}
-void imx8mn_get_boot_source(enum bootsource *src, int *instance)
- __alias(imx8mm_get_boot_source);
-
-void imx8mn_boot_save_loc(void)
- __alias(imx8mm_boot_save_loc);
-
void imx8mp_get_boot_source(enum bootsource *src, int *instance)
{
unsigned long addr;
void __iomem *src_base = IOMEM(MX8MP_SRC_BASE_ADDR);
uint32_t sbmr2 = readl(src_base + 0x70);
+ if (imx8mp_bootsource_serial(sbmr2)) {
+ *src = BOOTSOURCE_SERIAL;
+ return;
+ }
+
addr = IMX8M_BOOT_SW_INFO_POINTER_ADDR_A0;
__imx7_get_boot_source(src, instance, addr, sbmr2);
@@ -701,3 +750,9 @@ void imx8mp_boot_save_loc(void)
{
imx_boot_save_loc(imx8mp_get_boot_source);
}
+
+void imx8mn_get_boot_source(enum bootsource *src, int *instance)
+ __alias(imx8mp_get_boot_source);
+
+void imx8mn_boot_save_loc(void)
+ __alias(imx8mp_boot_save_loc);