From 46ce96c95455ae001ea018e1743e5aeb9b50d453 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 17 Jan 2021 20:50:56 +0100 Subject: [PATCH] Allwinner: atf: fix shutdown sequence --- ...mprove-system-shutdown-reset-sequenc.patch | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 projects/Allwinner/patches/atf/0002-allwinner-psci-Improve-system-shutdown-reset-sequenc.patch diff --git a/projects/Allwinner/patches/atf/0002-allwinner-psci-Improve-system-shutdown-reset-sequenc.patch b/projects/Allwinner/patches/atf/0002-allwinner-psci-Improve-system-shutdown-reset-sequenc.patch new file mode 100644 index 0000000000..ddf94e8077 --- /dev/null +++ b/projects/Allwinner/patches/atf/0002-allwinner-psci-Improve-system-shutdown-reset-sequenc.patch @@ -0,0 +1,82 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Sat, 16 Jan 2021 01:58:22 -0600 +Subject: [PATCH] allwinner: psci: Improve system shutdown/reset sequence + +- When the SCPI shutdown/reset command returns success, the SCPI + implementation is still waiting for the CPU to enter WFI. Do that. +- Peform board-level poweroff before CPU poweroff. If there is a PMIC + available, it will turn everything off including the CPUs, so doing + CPU poweroff first is a waste of cycles. +- During poweroff, attempt to turn off the local CPU using the ARISC. + This should use slightly less power than just an infinite WFI. +- Drop the WFI in the reset failure path. The panic will hang anyway. + +Change-Id: I897efecb3fe4e77a56041b97dd273156ec51ef8e +Signed-off-by: Samuel Holland +--- + plat/allwinner/common/sunxi_pm.c | 26 ++++++++++++++++---------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c +index 03985f40be55..038f2b7edb2f 100644 +--- a/plat/allwinner/common/sunxi_pm.c ++++ b/plat/allwinner/common/sunxi_pm.c +@@ -125,24 +125,29 @@ static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state) + + static void __dead2 sunxi_system_off(void) + { ++ u_register_t mpidr = read_mpidr(); ++ + gicv2_cpuif_disable(); + + if (scpi_available) { + /* Send the power down request to the SCP */ + uint32_t ret = scpi_sys_power_state(scpi_system_shutdown); + +- if (ret != SCP_OK) +- ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret); ++ if (ret == SCP_OK) ++ wfi(); ++ ++ ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret); + } + +- /* Turn off all secondary CPUs */ +- sunxi_disable_secondary_cpus(read_mpidr()); +- ++ /* Attempt to power down the board (may not return) */ + sunxi_power_down(); + +- udelay(1000); ++ /* Turn off all CPUs */ ++ sunxi_disable_secondary_cpus(mpidr); ++ sunxi_cpu_off(mpidr); ++ wfi(); ++ + ERROR("PSCI: Cannot turn off system, halting\n"); +- wfi(); + panic(); + } + +@@ -154,8 +159,10 @@ static void __dead2 sunxi_system_reset(void) + /* Send the system reset request to the SCP */ + uint32_t ret = scpi_sys_power_state(scpi_system_reboot); + +- if (ret != SCP_OK) +- ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret); ++ if (ret == SCP_OK) ++ wfi(); ++ ++ ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret); + } + + /* Reset the whole system when the watchdog times out */ +@@ -166,7 +173,6 @@ static void __dead2 sunxi_system_reset(void) + mdelay(1000); + + ERROR("PSCI: System reset failed\n"); +- wfi(); + panic(); + } +