[U-Boot,2/3] arm: mvebu: Add option to use UART xmodem protocol via kwboot
diff mbox

Message ID 1440505498-14944-2-git-send-email-sr@denx.de
State Accepted
Delegated to: Stefan Roese
Headers show

Commit Message

Stefan Roese Aug. 25, 2015, 12:24 p.m. UTC
This patch enables the use of the kwboot tool, to boot mainline U-Boot
on the Marvell Armada XP/38x SoC's. This is done by returning to the
SoC's BootROM after SPL has initialized the SDRAM. We need to make sure
to not reconfigure the internal register space and MBARs. Otherwise
the BootROM will not be able to continue after SPL jumps back to it.

To use this feature, please don't forget to change the BOOT_FROM line
in your board specfic kwbimage.cfg file this way:

    BOOT_FROM uart

Tested on these Marvell eval boards:
DB-MV784MP-GP - Armada XP
DB-88F6820-GP - Armada 38x

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Dirk Eibach <eibach@gdsys.de>
Cc: Kevin Smith <kevin.smith@elecsyscorp.com>
Cc: Luka Perkov <luka.perkov@sartura.hr>
---
 Makefile                               | 12 +++++++++++-
 arch/arm/mach-mvebu/Kconfig            | 10 ++++++++++
 arch/arm/mach-mvebu/include/mach/cpu.h |  2 ++
 arch/arm/mach-mvebu/include/mach/soc.h |  2 +-
 arch/arm/mach-mvebu/lowlevel_spl.S     | 16 ++++++++++++++++
 arch/arm/mach-mvebu/spl.c              | 25 +++++++++++++++++++++++++
 6 files changed, 65 insertions(+), 2 deletions(-)

Comments

Kevin Smith Aug. 25, 2015, 10:30 p.m. UTC | #1
On 08/25/2015 07:24 AM, Stefan Roese wrote:
> This patch enables the use of the kwboot tool, to boot mainline U-Boot
> on the Marvell Armada XP/38x SoC's. This is done by returning to the
> SoC's BootROM after SPL has initialized the SDRAM. We need to make sure
> to not reconfigure the internal register space and MBARs. Otherwise
> the BootROM will not be able to continue after SPL jumps back to it.
>
> To use this feature, please don't forget to change the BOOT_FROM line
> in your board specfic kwbimage.cfg file this way:
>
>      BOOT_FROM uart
>
> Tested on these Marvell eval boards:
> DB-MV784MP-GP - Armada XP
> DB-88F6820-GP - Armada 38x
>
> Signed-off-by: Stefan Roese <sr@denx.de>
Tested-by: Kevin Smith <kevin.smith@elecsyscorp.com>

Patch
diff mbox

diff --git a/Makefile b/Makefile
index 9919314..9d1905f 100644
--- a/Makefile
+++ b/Makefile
@@ -901,7 +901,7 @@  MKIMAGEFLAGS_u-boot.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \
 	-T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)
 
 MKIMAGEFLAGS_u-boot-spl.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \
-	-T kwbimage -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE)
+	-T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)
 
 MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
 		-R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage
@@ -909,8 +909,18 @@  MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
 u-boot.img u-boot.kwb u-boot.pbl: u-boot.bin FORCE
 	$(call if_changed,mkimage)
 
+# If the kwboot xmodem protocol is used, to boot U-Boot on the MVEBU
+# SoC's, the SPL U-Boot returns to the BootROM after it completes
+# the SDRAM setup. The BootROM expects no U-Boot header in the main
+# U-Boot image. So we need to combine SPL and u-boot.bin instead of
+# u-boot.img in this case.
+ifdef CONFIG_MVEBU_BOOTROM_UARTBOOT
+u-boot-spl.kwb: u-boot.bin spl/u-boot-spl.bin FORCE
+	$(call if_changed,mkimage)
+else
 u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE
 	$(call if_changed,mkimage)
+endif
 
 MKIMAGEFLAGS_u-boot-dtb.img = $(MKIMAGEFLAGS_u-boot.img)
 
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 1aa9640..79ff0e8 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 6fa4173..5e8bf0c 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 a8a6b27..64e5443 100644
--- a/arch/arm/mach-mvebu/include/mach/soc.h
+++ b/arch/arm/mach-mvebu/include/mach/soc.h
@@ -33,7 +33,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 69da7fe..c8cc8b2 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 af61ded..26ff1a2 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);
 }