allwinner: psci: Improve system shutdown/reset sequence

- When the SCPI shutdown/reset command returns success, the SCP 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 <samuel@sholland.org>
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index e6e9133..4e1a028 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -125,19 +125,20 @@
 		/* 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();
+		}
 
-	/* Turn off all secondary CPUs */
-	sunxi_cpu_power_off_others();
+		ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret);
+	}
 
+	/* Attempt to power down the board (may not return) */
 	sunxi_power_down();
 
-	udelay(1000);
-	ERROR("PSCI: Cannot turn off system, halting\n");
-	wfi();
-	panic();
+	/* Turn off all CPUs */
+	sunxi_cpu_power_off_others();
+	sunxi_cpu_power_off_self();
+	psci_power_down_wfi();
 }
 
 static void __dead2 sunxi_system_reset(void)
@@ -148,8 +149,11 @@
 		/* 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 */
@@ -160,7 +164,6 @@
 	mdelay(1000);
 
 	ERROR("PSCI: System reset failed\n");
-	wfi();
 	panic();
 }