Tegra194: wake: introduce support for RTC as wake source

This patch introduces support for adding RTC as a wake source to
exit System Suspend state.

Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Change-Id: Ib08d6e2ee7944cd46a91d272ceebffc67b8d7c66
diff --git a/plat/nvidia/tegra194/include/platform_def.h b/plat/nvidia/tegra194/include/platform_def.h
index af08357..1c9fff7 100644
--- a/plat/nvidia/tegra194/include/platform_def.h
+++ b/plat/nvidia/tegra194/include/platform_def.h
@@ -147,6 +147,7 @@
 #define TEGRA194_RTC_BASE		U(0x0C2A0000)
 #define TEGRA194_TMRUS_BASE		U(0x0C2E0000)
 #define SYS_CNT_BASE1			TEGRA194_TMRUS_BASE
+#define TEGRA194_AOWAKE_BASE		U(0x0C370000)
 #define TEGRA194_SCRATCH_BASE		U(0x0C390000)
 
 #ifndef __ASSEMBLY__
@@ -155,6 +156,7 @@
  * Platform functions
  */
 void tegra194_pwr_mgmt_setup(void);
+void tegra194_set_rtc_as_wakeup_source(void);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/plat/nvidia/tegra194/platform.mk b/plat/nvidia/tegra194/platform.mk
index 1d3c50a..d64e36d 100644
--- a/plat/nvidia/tegra194/platform.mk
+++ b/plat/nvidia/tegra194/platform.mk
@@ -16,7 +16,8 @@
 				plat/nvidia/tegra194/pwr_mgmt.c			\
 				plat/nvidia/tegra194/setup.c			\
 				plat/nvidia/tegra194/topology.c			\
-				plat/nvidia/tegra194/timers.c
+				plat/nvidia/tegra194/timers.c			\
+				plat/nvidia/tegra194/wake.c
 
 PLAT_TESTS_SKIP_LIST	:=	plat/nvidia/tegra194/tests_to_skip.txt
 
diff --git a/plat/nvidia/tegra194/setup.c b/plat/nvidia/tegra194/setup.c
index e83d303..a9d7843 100644
--- a/plat/nvidia/tegra194/setup.c
+++ b/plat/nvidia/tegra194/setup.c
@@ -36,6 +36,8 @@
 			MT_DEVICE | MT_RW | MT_NS),
 	MAP_REGION_FLAT(TEGRA194_TMRUS_BASE, 0x1000, /* 4KB */
 			MT_DEVICE | MT_RW | MT_NS),
+	MAP_REGION_FLAT(TEGRA194_AOWAKE_BASE, 0x1000, /* 4KB */
+			MT_DEVICE | MT_RW | MT_NS),
 	MAP_REGION_FLAT(TEGRA194_SCRATCH_BASE, 0x1000, /* 4KB */
 			MT_DEVICE | MT_RW | MT_NS),
 	MAP_REGION_FLAT(DRAM_BASE + TFTF_NVM_OFFSET, TFTF_NVM_SIZE,
@@ -69,4 +71,7 @@
 
 	/* Setup power management dependencies */
 	tegra194_pwr_mgmt_setup();
+
+	/* Configure system suspend wake sources */
+	tegra194_set_rtc_as_wakeup_source();
 }
diff --git a/plat/nvidia/tegra194/wake.c b/plat/nvidia/tegra194/wake.c
new file mode 100644
index 0000000..d4bfbd6
--- /dev/null
+++ b/plat/nvidia/tegra194/wake.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stddef.h>
+
+#include <utils_def.h>
+
+#define WAKE_AOWAKE_RTC_ID				U(73)
+#define WAKE_AOWAKE_CNTRL_73				U(0x124)
+#define WAKE_AOWAKE_MASK_W_73				U(0x2A4)
+#define WAKE_AOWAKE_STATUS_W_73				U(0x430)
+#define WAKE_AOWAKE_TIER2_CTRL_0			U(0x4B0)
+#define WAKE_AOWAKE_TIER2_ROUTING_31_0_0		U(0x4CC)
+#define WAKE_AOWAKE_TIER2_ROUTING_63_32_0		U(0x4D0)
+#define WAKE_AOWAKE_TIER2_ROUTING_95_64_0		U(0x4D4)
+
+
+#define WAKE_AOWAKE_TIER2_CTRL_0_INT_EN_TRUE		BIT_32(0)
+#define WAKE_AOWAKE_CNTRL_73_COAL_EN_FIELD		BIT_32(6)
+#define WAKE_AOWAKE_CNTRL_73_COAL_GRP_SEL_FIELD		BIT_32(5)
+#define WAKE_AOWAKE_CNTRL_73_LEVEL_FIELD		BIT_32(3)
+#define WAKE_AOWAKE_STATUS_W_73_CLEAR_FALSE		U(0)
+#define WAKE_AOWAKE_MASK_W_73_MASK_UNMASK		U(1)
+
+static inline void aowake_write_32(uint32_t offset, uint32_t value)
+{
+	mmio_write_32(TEGRA194_AOWAKE_BASE + offset, value);
+}
+
+void tegra194_set_rtc_as_wakeup_source(void)
+{
+	/*
+	 * Configure RTC as the wake source to tier2 = CCPLEX,
+	 * and disable others
+	 */
+	aowake_write_32(WAKE_AOWAKE_TIER2_ROUTING_31_0_0, 0U);
+	aowake_write_32(WAKE_AOWAKE_TIER2_ROUTING_63_32_0, 0U);
+	aowake_write_32(WAKE_AOWAKE_TIER2_ROUTING_95_64_0,
+			BIT_32(WAKE_AOWAKE_RTC_ID - 64));
+
+	/* Enable the tier 2 wake up */
+	aowake_write_32(WAKE_AOWAKE_TIER2_CTRL_0, WAKE_AOWAKE_TIER2_CTRL_0_INT_EN_TRUE);
+
+	/* Configure the RTC wake up source as per the golden register value */
+	aowake_write_32(WAKE_AOWAKE_CNTRL_73, WAKE_AOWAKE_CNTRL_73_COAL_EN_FIELD |
+			WAKE_AOWAKE_CNTRL_73_COAL_GRP_SEL_FIELD |
+			WAKE_AOWAKE_CNTRL_73_LEVEL_FIELD);
+
+	/* Clear current wake status of RTC then enable it as a wake source */
+	aowake_write_32(WAKE_AOWAKE_STATUS_W_73, WAKE_AOWAKE_STATUS_W_73_CLEAR_FALSE);
+	aowake_write_32(WAKE_AOWAKE_MASK_W_73, WAKE_AOWAKE_MASK_W_73_MASK_UNMASK);
+}