@@ -83,7 +83,7 @@ int meson_sm_get_serial(void *buffer, size_t size);
*/
int meson_sm_get_chip_id(struct meson_sm_chip_id *chip_id);
-enum {
+enum meson_reboot_mode {
REBOOT_REASON_COLD = 0,
REBOOT_REASON_NORMAL = 1,
REBOOT_REASON_RECOVERY = 2,
@@ -134,4 +134,100 @@ int meson_sm_pwrdm_set(size_t index, int cmd);
#define meson_sm_pwrdm_on(index) \
meson_sm_pwrdm_set(index, PWRDM_ON)
+/*
+ * Below is the list of SCPI_CMD commands, issued by U-Boot and passed to SCP
+ * co-processor via SMC to BL31 (TF-A). BL31 routes these commands to SCP
+ * via mailbox.
+ *
+ * Commands instruct the SCP how to set/control POC pins in order to choose
+ * first boot source, specified by the particular command below. These POC pins
+ * are readable by BootROM and used to determine the boot sequence. Usually,
+ * the normal default boot sequence, seen on production device is
+ * NAND/eMMC -> SD -> USB
+ *
+ * Commands below change the first boot source.
+ *
+ * NOTE:
+ * these commands are used along with meson_sm_set_bl1_first_boot_source() on
+ * Amlogic SoCs where ADNL burning protocol is utilized.
+ * Refer to meson_sm_set_usb_boot_mode() for the same functionality but on SoCs
+ * with Optimus burning protocol.
+ */
+
+/**
+ * define SCPI_CMD_USB_BOOT - sets the first boot source into USB with timeout
+ *
+ * Additionally, force the BootROM (BL1) to wait for the Host's enumeration
+ * with timeout
+ */
+#define SCPI_CMD_USB_BOOT 0xB0
+
+/**
+ * define SCPI_CMD_USB_UNBOOT - sets the first boot source into USB w/o timeout
+ *
+ * Additionally, force the BootROM to wait for the Host's enumeration with
+ * uninterruptible wait, i.e. forever
+ */
+#define SCPI_CMD_USB_UNBOOT 0xB1
+
+/**
+ * define SCPI_CMD_SDCARD_BOOT - sets the first boot source into SD card
+ */
+#define SCPI_CMD_SDCARD_BOOT 0xB2
+
+/**
+ * define SCPI_CMD_CLEAR_BOOT - sets the first boot source into default one
+ *
+ * BootROM follows a pre-defined boot sequence stored in SoC ROM code.
+ */
+#define SCPI_CMD_CLEAR_BOOT 0xB3
+
+/**
+ * meson_sm_set_bl1_first_boot_source - sets the first boot source for BootROM.
+ * @cmd: command to set first boot source visible to BootROM during boot.
+ * Use SCPI_CMD_* as commands.
+ *
+ * BootROM checks POC-pins (POC0, POC1, POC2) to determine in which order it
+ * must probe the various methods of booting the system. The order is usually
+ * pre-defined. But function changes the first boot source of that pre-defined
+ * order.
+ *
+ * @return: zero on success or error code on failure.
+ */
+int meson_sm_set_bl1_first_boot_source(u64 cmd);
+
+/**
+ * meson_sm_reboot - reboots device in a appropriate mode
+ * All possible modes described in &enum meson_reboot_mode
+ *
+ * @mode: reboot mode.
+ * @return: zero on success or error code on failure.
+ */
+int meson_sm_reboot(u64 mode);
+
+/**
+ * enum meson_usb_boot_mode - modes for meson_sm_set_usb_boot_mode()
+ * @FORCE_USB_BOOT: Forces BootROM to boot with firmware transferred by PC
+ * burning tool via USB. This mode has influence despite of the
+ * previously selected boot source. This mode persists between
+ * reboots and must be cleared.
+ * @CLEAR_USB_BOOT: Clears previous mode.
+ *
+ * These modes are used in conjunction with meson_sm_set_usb_boot_mode() on
+ * Amlogic SoCs where Optimus burning protocol is utilized.
+ */
+enum meson_usb_boot_mode {
+ CLEAR_USB_BOOT = 1,
+ FORCE_USB_BOOT = 2,
+};
+
+/**
+ * meson_sm_set_usb_boot_mode - sets the mode of usb interface that will be used during boot
+ * All possible modes described in &enum meson_usb_boot_mode
+ *
+ * @mode: reboot mode.
+ * @return: zero on success or error code on failure.
+ */
+int meson_sm_set_usb_boot_mode(u64 mode);
+
#endif /* __MESON_SM_H__ */
@@ -236,6 +236,17 @@ int meson_sm_get_reboot_reason(void)
return FIELD_GET(REBOOT_REASON_MASK, reason);
}
+static int meson_sm_call(u32 smc, struct pt_regs *regs, s32 *retval)
+{
+ struct udevice *dev;
+
+ dev = meson_get_sm_device();
+ if (IS_ERR(dev))
+ return PTR_ERR(dev);
+
+ return sm_call(dev, smc, retval, regs);
+}
+
int meson_sm_pwrdm_set(size_t index, int cmd)
{
struct udevice *dev;
@@ -256,3 +267,31 @@ int meson_sm_pwrdm_set(size_t index, int cmd)
return err;
}
+
+int meson_sm_set_bl1_first_boot_source(u64 cmd)
+{
+ struct pt_regs regs = { 0 };
+
+ regs.regs[1] = cmd;
+
+ return meson_sm_call(MESON_SMC_CMD_BL1_FIRST_BOOT_SRC_SET,
+ ®s, NULL);
+}
+
+int meson_sm_reboot(u64 mode)
+{
+ struct pt_regs regs = { 0 };
+
+ regs.regs[1] = mode;
+
+ return meson_sm_call(MESON_SMC_CMD_REBOOT_MODE_SET, ®s, NULL);
+}
+
+int meson_sm_set_usb_boot_mode(u64 mode)
+{
+ struct pt_regs regs = { 0 };
+
+ regs.regs[1] = mode;
+
+ return meson_sm_call(MESON_SMC_CMD_USB_BOOT_MODE_SET, ®s, NULL);
+}
@@ -168,8 +168,11 @@ static const struct meson_sm_data meson_sm_gxbb_data = {
.cmd = {
SET_CMD(MESON_SMC_CMD_EFUSE_READ, 0x82000030),
SET_CMD(MESON_SMC_CMD_EFUSE_WRITE, 0x82000031),
+ SET_CMD(MESON_SMC_CMD_USB_BOOT_MODE_SET, 0x82000043),
SET_CMD(MESON_SMC_CMD_CHIP_ID_GET, 0x82000044),
+ SET_CMD(MESON_SMC_CMD_BL1_FIRST_BOOT_SRC_SET, 0x82000087),
SET_CMD(MESON_SMC_CMD_PWRDM_SET, 0x82000093),
+ SET_CMD(MESON_SMC_CMD_REBOOT_MODE_SET, 0x84000009),
},
};
@@ -13,6 +13,9 @@ enum meson_smc_cmd {
MESON_SMC_CMD_EFUSE_WRITE, /* write efuse memory */
MESON_SMC_CMD_CHIP_ID_GET, /* readh chip unique id */
MESON_SMC_CMD_PWRDM_SET, /* do command at specified power domain */
+ MESON_SMC_CMD_BL1_FIRST_BOOT_SRC_SET, /* setup first boot source for BootROM */
+ MESON_SMC_CMD_REBOOT_MODE_SET, /* Reboot device in desired mode */
+ MESON_SMC_CMD_USB_BOOT_MODE_SET, /* Run boot from USB device */
MESON_SMC_CMD_COUNT,
};