rockchip: clear the power mode status via M0

Due to the PMU design, the PMU may not clear the WAKEUP bit after
wakeup, therefore, the state machine at the power mode may enter
the infinite loop during WFI.

There is a solution that we can use the M0 to monitor the WAKEUP
bit and clear it during power mode, then the state machine will be
recovered immediately. Then, the DUT can exit the WFI normally.

Change-Id: I303628553b728c214bf2d436bd3122032b5e669c
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index 29bf6dd..2dc70ec 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -35,6 +35,7 @@
 #include <platform_def.h>
 #include <plat_private.h>
 #include <rk3399_def.h>
+#include <rk3399m0.h>
 #include <soc.h>
 
 /* Table of regions to map using the MMU.  */
@@ -380,6 +381,20 @@
 		;
 }
 
+static void soc_m0_init(void)
+{
+	/* secure config for pmu M0 */
+	mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7));
+
+	/* set the execute address for M0 */
+	mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3),
+		      BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff,
+				      0xffff, 0));
+	mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7),
+		      BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf,
+				      0xf, 0));
+}
+
 void plat_rockchip_soc_init(void)
 {
 	secure_timer_init();
@@ -387,4 +402,5 @@
 	sgrf_init();
 	soc_global_soft_reset_init();
 	plat_rockchip_gpio_init();
+	soc_m0_init();
 }