diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 54182cb08..2c2bd680c 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -86,6 +86,20 @@ There are several build options: There is no reason to enable this feature if OP-TEE OS built with CFG_WITH_PAGER=n. Only set LLC_SRAM=1 if OP-TEE OS is built with CFG_WITH_PAGER=y. +- CM3_SYSTEM_RESET + + For Armada37x0 only, when ``CM3_SYSTEM_RESET=1``, the Cortex-M3 secure coprocessor will + be used for system reset. + TF-A will send command 0x0009 with a magic value via the rWTM mailbox interface to the + Cortex-M3 secure coprocessor. + The firmware running in the coprocessor must either implement this functionality or + ignore the 0x0009 command (which is true for the firmware from A3700-utils-marvell + repository). If this option is enabled but the firmware does not support this command, + an error message will be printed prior trying to reboot via the usual way. + + This option is needed on Turris MOX as a workaround to a HW bug which causes reset to + sometime hang the board. + - MARVELL_SECURE_BOOT Build trusted(=1)/non trusted(=0) image, default is non trusted. @@ -209,7 +223,8 @@ To build just TF-A without WTMI image (useful for A3720 Turris MOX board), run f .. code:: shell - > make USE_COHERENT_MEM=0 PLAT=a3700 BL33=/path/to/u-boot.bin CROSS_COMPILE=aarch64-linux-gnu- mrvl_bootimage + > make USE_COHERENT_MEM=0 PLAT=a3700 CM3_SYSTEM_RESET=1 BL33=/path/to/u-boot.bin \ + CROSS_COMPILE=aarch64-linux-gnu- mrvl_bootimage Supported MARVELL_PLATFORM are: - a3700 (for both A3720 DB and EspressoBin) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index e2022fac7..712b16202 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -1,5 +1,5 @@ # -# Copyright (C) 2018 Marvell International Ltd. +# Copyright (C) 2018-2020 Marvell International Ltd. # # SPDX-License-Identifier: BSD-3-Clause # https://spdx.org/licenses @@ -64,6 +64,10 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ $(MARVELL_DRV) +ifeq ($(CM3_SYSTEM_RESET),1) +BL31_SOURCES += $(PLAT_COMMON_BASE)/cm3_system_reset.c +endif + ifdef WTP DOIMAGEPATH := $(WTP) diff --git a/plat/marvell/armada/a3k/common/cm3_system_reset.c b/plat/marvell/armada/a3k/common/cm3_system_reset.c new file mode 100644 index 000000000..548ff5168 --- /dev/null +++ b/plat/marvell/armada/a3k/common/cm3_system_reset.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 Marek Behun, CZ.NIC + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include +#include + +#include + +/* Cortex-M3 Secure Processor Mailbox Registers */ +#define MVEBU_RWTM_PARAM0_REG (MVEBU_RWTM_REG_BASE) +#define MVEBU_RWTM_CMD_REG (MVEBU_RWTM_REG_BASE + 0x40) +#define MVEBU_RWTM_HOST_INT_RESET_REG (MVEBU_RWTM_REG_BASE + 0xC8) +#define MVEBU_RWTM_HOST_INT_MASK_REG (MVEBU_RWTM_REG_BASE + 0xCC) +#define MVEBU_RWTM_HOST_INT_SP_COMPLETE BIT(0) + +#define MVEBU_RWTM_REBOOT_CMD 0x0009 +#define MVEBU_RWTM_REBOOT_MAGIC 0xDEADBEEF + +static inline bool rwtm_completed(void) +{ + return (mmio_read_32(MVEBU_RWTM_HOST_INT_RESET_REG) & + MVEBU_RWTM_HOST_INT_SP_COMPLETE) != 0; +} + +static bool rwtm_wait(int ms) +{ + while (ms && !rwtm_completed()) { + mdelay(1); + --ms; + } + + return rwtm_completed(); +} + +void cm3_system_reset(void) +{ + int tries = 5; + + for (; tries > 0; --tries) { + mmio_clrbits_32(MVEBU_RWTM_HOST_INT_RESET_REG, + MVEBU_RWTM_HOST_INT_SP_COMPLETE); + + mmio_write_32(MVEBU_RWTM_PARAM0_REG, MVEBU_RWTM_REBOOT_MAGIC); + mmio_write_32(MVEBU_RWTM_CMD_REG, MVEBU_RWTM_REBOOT_CMD); + + if (rwtm_wait(10)) { + break; + } + + mdelay(100); + } + + /* If we reach here, the command is not implemented. */ + ERROR("System reset command not implemented in WTMI firmware!\n"); +} diff --git a/plat/marvell/armada/a3k/common/include/a3700_plat_def.h b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h index c7f40adc3..d23f5beea 100644 --- a/plat/marvell/armada/a3k/common/include/a3700_plat_def.h +++ b/plat/marvell/armada/a3k/common/include/a3700_plat_def.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Marvell International Ltd. + * Copyright (C) 2018-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -119,4 +119,10 @@ */ #define MVEBU_COMPHY_REG_BASE (MVEBU_REGS_BASE + 0x18300) +/***************************************************************************** + * Cortex-M3 Secure Processor Mailbox constants + ***************************************************************************** + */ +#define MVEBU_RWTM_REG_BASE (MVEBU_REGS_BASE + 0xB0000) + #endif /* A3700_PLAT_DEF_H */ diff --git a/plat/marvell/armada/a3k/common/include/a3700_pm.h b/plat/marvell/armada/a3k/common/include/a3700_pm.h index cc6cf436a..44dbb9f7d 100644 --- a/plat/marvell/armada/a3k/common/include/a3700_pm.h +++ b/plat/marvell/armada/a3k/common/include/a3700_pm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Marvell International Ltd. + * Copyright (C) 2016-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -48,4 +48,6 @@ struct pm_wake_up_src_config { struct pm_wake_up_src_config *mv_wake_up_src_config_get(void); +void cm3_system_reset(void); + #endif /* A3700_PM_H */ diff --git a/plat/marvell/armada/a3k/common/plat_pm.c b/plat/marvell/armada/a3k/common/plat_pm.c index f8ce6fe29..2bae37e3f 100644 --- a/plat/marvell/armada/a3k/common/plat_pm.c +++ b/plat/marvell/armada/a3k/common/plat_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Marvell International Ltd. + * Copyright (C) 2018-2020 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -763,6 +763,11 @@ static void __dead2 a3700_system_off(void) panic(); } +#pragma weak cm3_system_reset +void cm3_system_reset(void) +{ +} + /***************************************************************************** * A3700 handlers to reset the system ***************************************************************************** @@ -780,6 +785,9 @@ static void __dead2 a3700_system_reset(void) 2 * sizeof(uint64_t)); #endif + /* Use Cortex-M3 secure coprocessor for system reset */ + cm3_system_reset(); + /* Trigger the warm reset */ mmio_write_32(MVEBU_WARM_RESET_REG, MVEBU_WARM_RESET_MAGIC);