ARM: meson: Add boot device discovery
authorNeil Armstrong <narmstrong@baylibre.com>
Fri, 27 Jul 2018 12:10:00 +0000 (14:10 +0200)
committerNeil Armstrong <narmstrong@baylibre.com>
Mon, 26 Nov 2018 13:40:52 +0000 (14:40 +0100)
The Amlogic Meson SoCs ROM supports a boot over USB with a custom protocol.

When no other boot medium are available (or by forcing the USB mode), the
ROM sets the primary USB port as device mode and waits for a Host to
enumerate.

When enumerated, a custom protocol described at [1] permits writing to
memory and execute some specific FIP init code to run the loaded
Arm Trusted Firmware BL2 and BL3 stages before running the BL33 stage.

In this mode, we can load different binaries that can be used by U-boot
like a script image file.

This adds support for a custom USB boot stage only available when the
boot mode is USB and the script file at a pre-defined address is valid.
This support was heavily copied from the Sunxi Allwinner FEL U-Boot support.

The tool pyamlboot described at [2], permits using this boot mode on boards
exposing the first USB port, either as OTG or Host port.

[1] https://github.com/superna9999/pyamlboot/blob/master/PROTOCOL.md
[2] https://github.com/superna9999/pyamlboot/blob/master/README.md

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
arch/arm/include/asm/arch-meson/axg.h
arch/arm/include/asm/arch-meson/boot.h [new file with mode: 0644]
arch/arm/include/asm/arch-meson/gx.h
arch/arm/mach-meson/Kconfig
arch/arm/mach-meson/board-axg.c
arch/arm/mach-meson/board-common.c
arch/arm/mach-meson/board-gx.c
include/configs/meson64.h

index 28a38b791d1b86eb25e4d43b60491a7b84dc4f24..d293f2a8391e57d0da24f4856cc7d7e1bff9f7c9 100644 (file)
@@ -20,6 +20,7 @@
 #define AXG_AO_SEC_GP_CFG4     AXG_AO_ADDR(0x94)
 #define AXG_AO_SEC_GP_CFG5     AXG_AO_ADDR(0x95)
 
+#define AXG_AO_BOOT_DEVICE     0xF
 #define AXG_AO_MEM_SIZE_MASK   0xFFFF0000
 #define AXG_AO_MEM_SIZE_SHIFT  16
 #define AXG_AO_BL31_RSVMEM_SIZE_MASK   0xFFFF0000
diff --git a/arch/arm/include/asm/arch-meson/boot.h b/arch/arm/include/asm/arch-meson/boot.h
new file mode 100644 (file)
index 0000000..a90fe55
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __MESON_BOOT_H__
+#define __MESON_BOOT_H__
+
+/* Boot device */
+#define BOOT_DEVICE_RESERVED    0
+#define BOOT_DEVICE_EMMC        1
+#define BOOT_DEVICE_NAND        2
+#define BOOT_DEVICE_SPI         3
+#define BOOT_DEVICE_SD          4
+#define BOOT_DEVICE_USB         5
+
+int meson_get_boot_device(void);
+
+#endif /* __MESON_BOOT_H__ */
index 4bc9475d35e77e4cc867f9abb262247172ead77b..b781ba9475ba9b40486b29b420e6a99aabf2233b 100644 (file)
@@ -21,6 +21,7 @@
 #define GX_AO_SEC_GP_CFG4      GX_AO_ADDR(0x94)
 #define GX_AO_SEC_GP_CFG5      GX_AO_ADDR(0x95)
 
+#define GX_AO_BOOT_DEVICE      0xF
 #define GX_AO_MEM_SIZE_MASK    0xFFFF0000
 #define GX_AO_MEM_SIZE_SHIFT   16
 #define GX_AO_BL31_RSVMEM_SIZE_MASK    0xFFFF0000
index deddcc5ab07f5f2ea8a546e792d25d6ac158d719..11077bc6cc24ccf4c74c575192b2ef415430a4ba 100644 (file)
@@ -8,6 +8,7 @@ config MESON64_COMMON
        select DM_SERIAL
        select SYSCON
        select REGMAP
+       select BOARD_LATE_INIT
        imply CMD_DM
 
 config MESON_GX
index 014b25d61ab0108ffd26a42363869f6c4079635c..173905e762d2635eef46a7ab89b01889b1a25b57 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <asm/arch/boot.h>
 #include <asm/arch/eth.h>
 #include <asm/arch/axg.h>
 #include <asm/arch/mem.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+int meson_get_boot_device(void)
+{
+       return readl(AXG_AO_SEC_GP_CFG0) & AXG_AO_BOOT_DEVICE;
+}
+
 /* Configure the reserved memory zones exported by the secure registers
  * into EFI and DTB reserved memory entries.
  */
index 8c4f3074fbc738e3c81dc17ef322f830c4832ee5..8c41301674e3eafb67f69f161f80b610c29e7f20 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <asm/arch/boot.h>
 #include <linux/libfdt.h>
 #include <linux/err.h>
 #include <asm/arch/mem.h>
@@ -66,6 +67,50 @@ void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
        }
 }
 
+static void meson_set_boot_source(void)
+{
+       const char *source;
+
+       switch (meson_get_boot_device()) {
+       case BOOT_DEVICE_EMMC:
+               source = "emmc";
+               break;
+
+       case BOOT_DEVICE_NAND:
+               source = "nand";
+               break;
+
+       case BOOT_DEVICE_SPI:
+               source = "spi";
+               break;
+
+       case BOOT_DEVICE_SD:
+               source = "sd";
+               break;
+
+       case BOOT_DEVICE_USB:
+               source = "usb";
+               break;
+
+       default:
+               source = "unknown";
+       }
+
+       env_set("boot_source", source);
+}
+
+__weak int meson_board_late_init(void)
+{
+       return 0;
+}
+
+int board_late_init(void)
+{
+       meson_set_boot_source();
+
+       return meson_board_late_init();
+}
+
 void reset_cpu(ulong addr)
 {
        psci_system_reset();
index f1397f87c5b643d53ff276602cb00c50d0eb3fbf..e41552db523c5923b03d066eaf28a3d0bbe885de 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <asm/arch/boot.h>
 #include <asm/arch/eth.h>
 #include <asm/arch/gx.h>
 #include <asm/arch/mem.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+int meson_get_boot_device(void)
+{
+       return readl(GX_AO_SEC_GP_CFG0) & GX_AO_BOOT_DEVICE;
+}
+
 /* Configure the reserved memory zones exported by the secure registers
  * into EFI and DTB reserved memory entries.
  */
index f961f43871c3bf4394fd137e238ae3f89dfa081c..40ac079dfc8f5fec80375bc47d7a27da64a7e084 100644 (file)
 #define CONFIG_SYS_LOAD_ADDR           CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_BOOTM_LEN           (64 << 20) /* 64 MiB */
 
+/* ROM USB boot support, auto-execute boot.scr at scriptaddr */
+#define BOOTENV_DEV_ROMUSB(devtypeu, devtypel, instance) \
+       "bootcmd_romusb=" \
+               "if test \"${boot_source}\" = \"usb\" && " \
+                               "test -n \"${scriptaddr}\"; then " \
+                       "echo '(ROM USB boot)'; " \
+                       "source ${scriptaddr}; " \
+               "fi\0"
+
+#define BOOTENV_DEV_NAME_ROMUSB(devtypeu, devtypel, instance)  \
+               "romusb "
+
 #ifdef CONFIG_CMD_USB
 #define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0)
 #else
@@ -36,6 +48,7 @@
 
 #ifndef BOOT_TARGET_DEVICES
 #define BOOT_TARGET_DEVICES(func) \
+       func(ROMUSB, romusb, na)  \
        func(MMC, mmc, 0) \
        func(MMC, mmc, 1) \
        func(MMC, mmc, 2) \