@@ -23,6 +23,7 @@
#define AXG_AO_SEC_GP_CFG3 AXG_AO_ADDR(0x93)
#define AXG_AO_SEC_GP_CFG4 AXG_AO_ADDR(0x94)
#define AXG_AO_SEC_GP_CFG5 AXG_AO_ADDR(0x95)
+#define AXG_AO_SEC_GP_CFG7 AXG_AO_ADDR(0x97)
#define AXG_AO_BOOT_DEVICE 0xF
#define AXG_AO_MEM_SIZE_MASK 0xFFFF0000
@@ -31,4 +32,15 @@
#define AXG_AO_BL31_RSVMEM_SIZE_SHIFT 16
#define AXG_AO_BL32_RSVMEM_SIZE_MASK 0xFFFF
+#if CONFIG_IS_ENABLED(CMD_OPTIMUS)
+/**
+ * is_tpl_loaded_from_usb - Checks, that this instance of U-boot was
+ * loaded from USB during firmware update
+ * process.
+ *
+ * returns: true, if so.
+ */
+int is_tpl_loaded_from_usb(void);
+#endif
+
#endif /* __AXG_H__ */
@@ -4,12 +4,14 @@
* (C) Copyright 2018 Neil Armstrong <narmstrong@baylibre.com>
*/
+#include <command.h>
#include <init.h>
#include <net.h>
#include <asm/arch/boot.h>
#include <asm/arch/eth.h>
#include <asm/arch/axg.h>
#include <asm/arch/mem.h>
+#include <asm/arch-meson/sm.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/armv8/mmu.h>
@@ -62,6 +64,16 @@ phys_size_t get_effective_memsize(void)
>> AXG_AO_MEM_SIZE_SHIFT) * SZ_1M;
}
+#if CONFIG_IS_ENABLED(CMD_OPTIMUS)
+int is_tpl_loaded_from_usb(void)
+{
+ const int boot_id = meson_get_boot_device();
+ const unsigned int force_usb_boot = readl(AXG_AO_SEC_GP_CFG7);
+
+ return (boot_id == BOOT_DEVICE_USB || (force_usb_boot & BIT(31)));
+}
+#endif
+
static struct mm_region axg_mem_map[] = {
{
.virt = 0x0UL,
@@ -16,6 +16,7 @@
#include <linux/libfdt.h>
#include <linux/err.h>
#include <asm/arch/a1.h>
+#include <asm/arch/axg.h>
#include <asm/arch/mem.h>
#include <asm/arch/sm.h>
#include <asm/armv8/mmu.h>
@@ -144,6 +145,18 @@ __weak int meson_board_late_init(void)
return 0;
}
+static void meson_board_try_enter_optimus(void)
+{
+#if (IS_ENABLED(CONFIG_CMD_OPTIMUS))
+ if (!is_tpl_loaded_from_usb())
+ return;
+
+ meson_sm_set_usb_boot_mode(CLEAR_USB_BOOT);
+
+ run_command("optimus", 0);
+#endif
+}
+
static void meson_board_try_enter_adnl(void)
{
#if (IS_ENABLED(CONFIG_CMD_ADNL))
@@ -162,6 +175,8 @@ int board_late_init(void)
meson_board_try_enter_adnl();
+ meson_board_try_enter_optimus();
+
return meson_board_late_init();
}