Tegra: Add support for fake system suspend

This patch adds support for fake system suspend (SC7).
This is a debug mode, to ensure that a different code path is
executed for cases like pre-silicon development, where a
full-fledged SC7 is not possible in early stages.

This particular patch ensures that, if fake system suspend is
enabled (denoted by tegra_fake_system_suspend variable
having a non-zero value), instead of calling WFI, a request
for a warm reset is made for starting the SC7 exit procedure.

This ensures that the code path of kernel->ATF and back to
kernel is executed without depending on other components
involved in SC7 code path.

Additionally, this patch also adds support for SMC call
from kernel, enabling fake system suspend mode.

Signed-off-by: Vignesh Radhakrishnan <vigneshr@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index 4dd4353..b01dcb0 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -37,6 +37,7 @@
 #include <memctrl.h>
 #include <runtime_svc.h>
 #include <tegra_private.h>
+#include <tegra_platform.h>
 
 /*******************************************************************************
  * Common Tegra SiP SMCs
@@ -44,8 +45,15 @@
 #define TEGRA_SIP_NEW_VIDEOMEM_REGION		0x82000003
 #define TEGRA_SIP_FIQ_NS_ENTRYPOINT		0x82000005
 #define TEGRA_SIP_FIQ_NS_GET_CONTEXT		0x82000006
+#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND	0xC2000007
 
 /*******************************************************************************
+ * Fake system suspend mode control var
+ ******************************************************************************/
+extern uint8_t tegra_fake_system_suspend;
+
+
+/*******************************************************************************
  * SoC specific SiP handler
  ******************************************************************************/
 #pragma weak plat_sip_handler
@@ -144,6 +152,26 @@
 		SMC_RET0(handle);
 		break;
 
+	case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
+		/*
+		 * System suspend fake mode is set if we are on VDK and we make
+		 * a debug SIP call. This mode ensures that we excercise debug
+		 * path instead of the regular code path to suit the pre-silicon
+		 * platform needs. These include replacing the call to WFI by
+		 * a warm reset request.
+		 */
+		if (tegra_platform_is_emulation() != 0U) {
+
+			tegra_fake_system_suspend = 1;
+			SMC_RET1(handle, 0);
+		}
+
+		/*
+		 * We return to the external world as if this SIP is not
+		 * implemented in case, we are not running on VDK.
+		 */
+		break;
+
 	default:
 		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
 		break;