meson: gxl: Fix reset and power off
authorRemi Pommarel <repk@triplefau.lt>
Thu, 4 Apr 2019 21:12:56 +0000 (23:12 +0200)
committerRemi Pommarel <repk@triplefau.lt>
Fri, 2 Aug 2019 11:54:16 +0000 (13:54 +0200)
Before CPU enters standby state (wfi), the AP needs to signal the SCP
through PSCI mailbox.

Also at boot time the AP has to wait for the SCP to be ready before
sending the first scpi commands or it can crash.

Change-Id: Iacc99f5bec745ad71922c5ea07ca5b87088133b6
Signed-off-by: Remi Pommarel <repk@triplefau.lt>
plat/meson/gxl/gxl_bl31_setup.c
plat/meson/gxl/gxl_def.h
plat/meson/gxl/gxl_pm.c

index f8ce6605bdbcf4ec21e61448e724504a168ac3c6..b1da7942b6d375ac548a8bb810b51070a178d7c7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,7 @@
 #include <common/interrupt_props.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
+#include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 
 #include "gxl_private.h"
@@ -100,12 +101,19 @@ void bl31_plat_arch_setup(void)
        enable_mmu_el3(0);
 }
 
+static inline bool gxl_scp_ready(void)
+{
+       return GXBB_AO_RTI_SCP_IS_READY(mmio_read_32(GXBB_AO_RTI_SCP_STAT));
+}
+
 static inline void gxl_scp_boot(void)
 {
        scpi_upload_scp_fw(bl30_image_info.image_base,
                        bl30_image_info.image_size, 0);
        scpi_upload_scp_fw(bl301_image_info.image_base,
                        bl301_image_info.image_size, 1);
+       while (!gxl_scp_ready())
+               ;
 }
 
 /*******************************************************************************
index ada26560c45a6ff9909b62095fe6980e1a18149b..089fa8db906bbd44cd1d38d195aede9cb90f808b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #define GXBB_SYS_CPU_CFG7                      UL(0xC8834664)
 
 #define GXBB_AO_RTI_STATUS_REG3                        UL(0xDA10001C)
+#define GXBB_AO_RTI_SCP_STAT                   UL(0xDA10023C)
+#define GXBB_AO_RTI_SCP_READY_OFF              U(0x14)
+#define GXBB_A0_RTI_SCP_READY_MASK             U(3)
+#define GXBB_AO_RTI_SCP_IS_READY(v)            \
+       ((((v) >> GXBB_AO_RTI_SCP_READY_OFF) & \
+         GXBB_A0_RTI_SCP_READY_MASK) == GXBB_A0_RTI_SCP_READY_MASK)
 
 #define GXBB_HIU_MAILBOX_SET_0                 UL(0xDA83C404)
 #define GXBB_HIU_MAILBOX_STAT_0                        UL(0xDA83C408)
index d9b69ef8235b03e16a0d235efb35fea52afa2831..5136c89aaab45556898d8dd8fde8dabdb12b76e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 static uintptr_t gxbb_sec_entrypoint;
 static volatile uint32_t gxbb_cpu0_go;
 
-static void gxbb_program_mailbox(u_register_t mpidr, uint64_t value)
+static void gxl_pm_set_reset_addr(u_register_t mpidr, uint64_t value)
 {
        unsigned int core = plat_gxbb_calc_core_pos(mpidr);
        uintptr_t cpu_mailbox_addr = GXBB_PSCI_MAILBOX_BASE + (core << 4);
 
        mmio_write_64(cpu_mailbox_addr, value);
-       flush_dcache_range(cpu_mailbox_addr, sizeof(uint64_t));
+}
+
+static void gxl_pm_reset(u_register_t mpidr)
+{
+       unsigned int core = plat_gxbb_calc_core_pos(mpidr);
+       uintptr_t cpu_mailbox_addr = GXBB_PSCI_MAILBOX_BASE + (core << 4) + 8;
+
+       mmio_write_32(cpu_mailbox_addr, 0);
 }
 
 static void __dead2 gxbb_system_reset(void)
 {
        INFO("BL31: PSCI_SYSTEM_RESET\n");
 
+       u_register_t mpidr = read_mpidr_el1();
        uint32_t status = mmio_read_32(GXBB_AO_RTI_STATUS_REG3);
+       int ret;
 
        NOTICE("BL31: Reboot reason: 0x%x\n", status);
 
@@ -50,13 +59,15 @@ static void __dead2 gxbb_system_reset(void)
 
        mmio_write_32(GXBB_AO_RTI_STATUS_REG3, status);
 
-       int ret = scpi_sys_power_state(SCPI_SYSTEM_REBOOT);
+       ret = scpi_sys_power_state(SCPI_SYSTEM_REBOOT);
 
        if (ret != 0) {
-               ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %u\n", ret);
+               ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret);
                panic();
        }
 
+       gxl_pm_reset(mpidr);
+
        wfi();
 
        ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n");
@@ -67,14 +78,18 @@ static void __dead2 gxbb_system_off(void)
 {
        INFO("BL31: PSCI_SYSTEM_OFF\n");
 
-       unsigned int ret = scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
+       u_register_t mpidr = read_mpidr_el1();
+       int ret;
+
+       ret = scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
 
        if (ret != 0) {
-               ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %u\n", ret);
+               ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret);
                panic();
        }
 
-       gxbb_program_mailbox(read_mpidr_el1(), 0);
+       gxl_pm_set_reset_addr(mpidr, 0);
+       gxl_pm_reset(mpidr);
 
        wfi();
 
@@ -101,7 +116,7 @@ static int32_t gxbb_pwr_domain_on(u_register_t mpidr)
                return PSCI_E_SUCCESS;
        }
 
-       gxbb_program_mailbox(mpidr, gxbb_sec_entrypoint);
+       gxl_pm_set_reset_addr(mpidr, gxbb_sec_entrypoint);
        scpi_set_css_power_state(mpidr,
                                 SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON);
        dmbsy();
@@ -133,10 +148,6 @@ static void gxbb_pwr_domain_off(const psci_power_state_t *target_state)
 {
        u_register_t mpidr = read_mpidr_el1();
        unsigned int core = plat_gxbb_calc_core_pos(mpidr);
-       uintptr_t addr = GXBB_PSCI_MAILBOX_BASE + 8 + (core << 4);
-
-       mmio_write_32(addr, 0xFFFFFFFF);
-       flush_dcache_range(addr, sizeof(uint32_t));
 
        gicv2_cpuif_disable();