From 43d4a2910dd7b1ed46719b31a03a3d860d4875b1 Mon Sep 17 00:00:00 2001 From: Remi Pommarel Date: Thu, 4 Apr 2019 23:12:56 +0200 Subject: [PATCH] meson: gxl: Fix reset and power off 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 --- plat/meson/gxl/gxl_bl31_setup.c | 10 ++++++++- plat/meson/gxl/gxl_def.h | 8 ++++++- plat/meson/gxl/gxl_pm.c | 37 +++++++++++++++++++++------------ 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/plat/meson/gxl/gxl_bl31_setup.c b/plat/meson/gxl/gxl_bl31_setup.c index f8ce6605b..b1da7942b 100644 --- a/plat/meson/gxl/gxl_bl31_setup.c +++ b/plat/meson/gxl/gxl_bl31_setup.c @@ -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 #include #include +#include #include #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()) + ; } /******************************************************************************* diff --git a/plat/meson/gxl/gxl_def.h b/plat/meson/gxl/gxl_def.h index ada26560c..089fa8db9 100644 --- a/plat/meson/gxl/gxl_def.h +++ b/plat/meson/gxl/gxl_def.h @@ -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 */ @@ -91,6 +91,12 @@ #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) diff --git a/plat/meson/gxl/gxl_pm.c b/plat/meson/gxl/gxl_pm.c index d9b69ef82..5136c89aa 100644 --- a/plat/meson/gxl/gxl_pm.c +++ b/plat/meson/gxl/gxl_pm.c @@ -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 */ @@ -27,20 +27,29 @@ 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();