]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
plat: marvell: armada: a3k: support doing system reset via CM3 secure coprocessor
authorMarek Behún <marek.behun@nic.cz>
Tue, 5 Jan 2021 13:01:05 +0000 (14:01 +0100)
committerMarek Behún <marek.behun@nic.cz>
Tue, 5 Jan 2021 13:01:51 +0000 (14:01 +0100)
Introduce a new build option CM3_SYSTEM_RESET for A3700 platform, which,
when enabled, adds code to the PSCI reset handler to try to do system
reset by the WTMI firmware running on the Cortex-M3 secure coprocessor.
(This function is exposed via the mailbox interface.)

The reason is that the Turris MOX board has a HW bug which causes reset
to hang unpredictably. This issue can be solved by putting the board in
a specific state before reset.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Change-Id: I3f60b9f244f334adcd33d6db6a361fbc8b8d209f

docs/plat/marvell/armada/build.rst
plat/marvell/armada/a3k/common/a3700_common.mk
plat/marvell/armada/a3k/common/cm3_system_reset.c [new file with mode: 0644]
plat/marvell/armada/a3k/common/include/a3700_plat_def.h
plat/marvell/armada/a3k/common/include/a3700_pm.h
plat/marvell/armada/a3k/common/plat_pm.c

index 54182cb0829f50ef53e61ca02ed681b0b93078cc..2c2bd680c6111c1f7fd3ccc3c5499482afcb1c92 100644 (file)
@@ -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)
index e2022fac7fea0615b2f509dc9257061c0b1ea06c..712b162021751fc38dc7b95189f5964c4a5571b4 100644 (file)
@@ -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 (file)
index 0000000..548ff51
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 Marek Behun, CZ.NIC
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <mvebu_def.h>
+
+/* 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");
+}
index c7f40adc3eef2f88fc56e9dd0dc76489d0b03d6c..d23f5beeadb3aa6234c5f956a29a1b239dfca23b 100644 (file)
@@ -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
  */
 #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 */
index cc6cf436ab5d5c81470f3299d869fc0f491f6f8e..44dbb9f7d29808f612bbcf54c8f81b76ab65ecd7 100644 (file)
@@ -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 */
index f8ce6fe29ee91a380a292261b05adbacf7472203..2bae37e3f9ce6ab696d39434ba25e2d35c408d16 100644 (file)
@@ -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);