arm: mvebu: Add runtime detection of UART (xmodem) boot-mode
This patch adds runtime detection of the Marvell UART boot-mode (xmodem
protocol). If this boot-mode is detected, SPL will return to the
BootROM to continue the UART booting.
With this patch its now possible, to generate a U-Boot image that
can be booted either from the strapped boot-device (e.g. SPI NOR, MMC,
etc) or via the xmodem protocol from the UART. In the UART case,
the kwboot tool will dynamically insert the UART boot-device type
into the image. And also patch the load address in the header, so
that the mkimage header will be skipped (as its not expected by the
Marvell BootROM).
This simplifies the development for Armada XP / 38x based boards.
As no special images need to be generated by selecting the
MVEBU_BOOTROM_UARTBOOT Kconfig option.
Since the Kconfig option MVEBU_BOOTROM_UARTBOOT is not needed any
more, its now completely removed.
Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Luka Perkov <luka.perkov@sartura.hr>
Cc: Dirk Eibach <dirk.eibach@gdsys.cc>
Cc: Phil Sutter <phil@nwl.cc>
Cc: Kevin Smith <kevin.smith@elecsyscorp.com>
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index d96b2ae..a15c4b7 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -48,14 +48,4 @@
config SYS_SOC
default "mvebu"
-config MVEBU_BOOTROM_UARTBOOT
- bool "Use kwboot to boot via BootROM xmodem protocol"
- help
- This option provides support for booting via the Marvell
- xmodem protocol, used by the kwboot tool.
-
- Please don't forget to configure the boot device in
- the board specific kwbimage.cfg file this way:
- BOOT_FROM uart
-
endif
diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h
index e27a36d..c696fc6 100644
--- a/arch/arm/mach-mvebu/include/mach/soc.h
+++ b/arch/arm/mach-mvebu/include/mach/soc.h
@@ -96,6 +96,12 @@
#define MVCPU_WIN_ENABLE CPU_WIN_ENABLE
#define MVCPU_WIN_DISABLE CPU_WIN_DISABLE
+/* BootROM error register (also includes some status infos) */
+#define CONFIG_BOOTROM_ERR_REG (MVEBU_REGISTER(0x182d0))
+#define BOOTROM_ERR_MODE_OFFS 28
+#define BOOTROM_ERR_MODE_MASK (0xf << BOOTROM_ERR_MODE_OFFS)
+#define BOOTROM_ERR_MODE_UART 0x6
+
#if defined(CONFIG_ARMADA_38X)
/* SAR values for Armada 38x */
#define CONFIG_SAR_REG (MVEBU_REGISTER(0x18600))
@@ -106,7 +112,7 @@
#define SAR_BOOT_DEVICE_MASK (0x1f << SAR_BOOT_DEVICE_OFFS)
#define BOOT_DEV_SEL_OFFS 4
-#define BOOT_DEV_SEL_MASK (0x1f << BOOT_DEV_SEL_OFFS)
+#define BOOT_DEV_SEL_MASK (0x3f << BOOT_DEV_SEL_OFFS)
#define BOOT_FROM_UART 0x28
#define BOOT_FROM_SPI 0x32
diff --git a/arch/arm/mach-mvebu/lowlevel_spl.S b/arch/arm/mach-mvebu/lowlevel_spl.S
index 2e2181e..49e0b90 100644
--- a/arch/arm/mach-mvebu/lowlevel_spl.S
+++ b/arch/arm/mach-mvebu/lowlevel_spl.S
@@ -5,7 +5,6 @@
#include <config.h>
#include <linux/linkage.h>
-#ifdef CONFIG_MVEBU_BOOTROM_UARTBOOT
ENTRY(save_boot_params)
stmfd sp!, {r0 - r12, lr} /* @ save registers on stack */
ldr r12, =CONFIG_SPL_BOOTROM_SAVE
@@ -19,11 +18,6 @@
mov r0, #0x0 /* @ return value: 0x0 NO_ERR */
ldmfd sp!, {r0 - r12, pc} /* @ restore regs and return */
ENDPROC(return_to_bootrom)
-#else
-ENTRY(save_boot_params)
- b save_boot_params_ret
-ENDPROC(save_boot_params)
-#endif
/*
* cache_inv - invalidate Cache line
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index 778996e..0879873 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -20,8 +20,23 @@
u32 val;
u32 boot_device;
+ /*
+ * First check, if UART boot-mode is active. This can only
+ * be done, via the bootrom error register. Here the
+ * MSB marks if the UART mode is active.
+ */
+ val = readl(CONFIG_BOOTROM_ERR_REG);
+ boot_device = (val & BOOTROM_ERR_MODE_MASK) >> BOOTROM_ERR_MODE_OFFS;
+ debug("BOOTROM_REG=0x%08x boot_device=0x%x\n", val, boot_device);
+ if (boot_device == BOOTROM_ERR_MODE_UART)
+ return BOOT_DEVICE_UART;
+
+ /*
+ * Now check the SAR register for the strapped boot-device
+ */
val = readl(CONFIG_SAR_REG); /* SAR - Sample At Reset */
boot_device = (val & BOOT_DEV_SEL_MASK) >> BOOT_DEV_SEL_OFFS;
+ debug("SAR_REG=0x%08x boot_device=0x%x\n", val, boot_device);
switch (boot_device) {
#ifdef CONFIG_SPL_MMC_SUPPORT
case BOOT_FROM_MMC:
@@ -90,7 +105,6 @@
/* Setup DDR */
ddr3_init();
-#ifdef CONFIG_MVEBU_BOOTROM_UARTBOOT
/*
* Return to the BootROM to continue the Marvell xmodem
* UART boot protocol. As initiated by the kwboot tool.
@@ -102,6 +116,6 @@
* need to return to the BootROM to enable this xmodem
* UART download.
*/
- return_to_bootrom();
-#endif
+ if (get_boot_device() == BOOT_DEVICE_UART)
+ return_to_bootrom();
}