summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-mvebu/Kconfig10
-rw-r--r--arch/arm/mach-mvebu/include/mach/cpu.h2
-rw-r--r--arch/arm/mach-mvebu/include/mach/soc.h2
-rw-r--r--arch/arm/mach-mvebu/lowlevel_spl.S16
-rw-r--r--arch/arm/mach-mvebu/spl.c25
5 files changed, 54 insertions, 1 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 1aa964091a..79ff0e8278 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -18,4 +18,14 @@ endchoice
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/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h
index 6fa41736e2..5e8bf0c4ce 100644
--- a/arch/arm/mach-mvebu/include/mach/cpu.h
+++ b/arch/arm/mach-mvebu/include/mach/cpu.h
@@ -119,6 +119,8 @@ int mvebu_mbus_probe(struct mbus_win windows[], int count);
int mvebu_soc_family(void);
u32 mvebu_get_nand_clock(void);
+void return_to_bootrom(void);
+
int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks);
/*
diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h
index 02c21bcded..22abde080e 100644
--- a/arch/arm/mach-mvebu/include/mach/soc.h
+++ b/arch/arm/mach-mvebu/include/mach/soc.h
@@ -31,7 +31,7 @@
/* SOC specific definations */
#define INTREG_BASE 0xd0000000
#define INTREG_BASE_ADDR_REG (INTREG_BASE + 0x20080)
-#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SYS_MVEBU_DDR_A38X)
+#if defined(CONFIG_SPL_BUILD)
/*
* On A38x switching the regs base address without running from
* SDRAM doesn't seem to work. So let the SPL still use the
diff --git a/arch/arm/mach-mvebu/lowlevel_spl.S b/arch/arm/mach-mvebu/lowlevel_spl.S
index 69da7fe7af..2e2181ecea 100644
--- a/arch/arm/mach-mvebu/lowlevel_spl.S
+++ b/arch/arm/mach-mvebu/lowlevel_spl.S
@@ -5,10 +5,26 @@
#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
+ str sp, [r12]
b save_boot_params_ret
ENDPROC(save_boot_params)
+ENTRY(return_to_bootrom)
+ ldr r12, =CONFIG_SPL_BOOTROM_SAVE
+ ldr sp, [r12]
+ 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
* r0 - dest
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index af61ded42e..26ff1a24ac 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -34,8 +34,18 @@ void board_init_f(ulong dummy)
/* Set global data pointer */
gd = &gdata;
+#ifndef CONFIG_MVEBU_BOOTROM_UARTBOOT
+ /*
+ * Only call arch_cpu_init() when not returning to the
+ * Marvell BootROM, which is done when booting via
+ * the xmodem protocol (kwboot tool). Otherwise the
+ * internal register will get remapped and the BootROM
+ * can't continue to run correctly.
+ */
+
/* Linux expects the internal registers to be at 0xf1000000 */
arch_cpu_init();
+#endif
/*
* Pin muxing needs to be done before UART output, since
@@ -54,5 +64,20 @@ void board_init_f(ulong dummy)
/* 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.
+ *
+ * This can only be done by the BootROM and not by the
+ * U-Boot SPL infrastructure, since the beginning of the
+ * image is already read and interpreted by the BootROM.
+ * SPL has no chance to receive this information. So we
+ * need to return to the BootROM to enable this xmodem
+ * UART download.
+ */
+ return_to_bootrom();
+#endif
+
board_init_r(NULL, 0);
}
OpenPOWER on IntegriCloud