Add NXP's i.MX8 SoCs SRTC SIP(silicon provider) service support

On NXP's i.MX8 SoCs with system controller inside, SRTC is maintained
in SCFW(system controller firmware), it can ONLY be accessed in EL3
mode for some functions like changing time, setting alarm etc,, so Linux
needs to use SMC call to trap into TF-A using SIP protocal, and TF-A will
call SCFW IPC API to operate the SRTC function.

This patch adds SRTC SIP service support and enable it for i.MX8QM/i.MX8QXP.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
diff --git a/plat/imx/common/imx8_sip_svc.c b/plat/imx/common/imx8_sip_svc.c
new file mode 100644
index 0000000..26bd6a7
--- /dev/null
+++ b/plat/imx/common/imx8_sip_svc.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright 2017-2018 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <runtime_svc.h>
+#include <std_svc.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <uuid.h>
+#include <string.h>
+#include <bl_common.h>
+#include <imx_sip.h>
+
+/* Setup i.MX platform specific services Services */
+static int32_t plat_svc_setup(void)
+{
+	/* gpc init ?*/
+	NOTICE("sip svc init\n");
+	return 0;
+}
+
+/* i.MX platform specific service SMC handler */
+uintptr_t imx_svc_smc_handler(uint32_t smc_fid,
+			      u_register_t x1,
+			      u_register_t x2,
+			      u_register_t x3,
+			      u_register_t x4,
+			      void *cookie,
+			      void *handle,
+			      u_register_t flags)
+{
+	switch (smc_fid) {
+#if defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX)
+	case  IMX_SIP_SRTC:
+		return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4);
+#endif
+	default:
+		WARN("Unimplemented SIP Service Call: 0x%x \n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+		break;
+	}
+}
+
+/* Rigister SIP Service Calls as runtime service */
+DECLARE_RT_SVC(
+		imx_svc,
+		OEN_SIP_START,
+		OEN_SIP_END,
+		SMC_TYPE_FAST,
+		plat_svc_setup,
+		imx_svc_smc_handler
+);
diff --git a/plat/imx/common/include/imx_sip.h b/plat/imx/common/include/imx_sip.h
new file mode 100644
index 0000000..3367229
--- /dev/null
+++ b/plat/imx/common/include/imx_sip.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SOC_IMX_SIP_H
+#define __SOC_IMX_SIP_H
+
+#define IMX_SIP_SRTC			0xC2000002
+#define IMX_SIP_SRTC_SET_TIME		0x00
+#define IMX_SIP_SRTC_START_WDOG		0x01
+#define IMX_SIP_SRTC_STOP_WDOG		0x02
+#define IMX_SIP_SRTC_SET_WDOG_ACT	0x03
+#define IMX_SIP_SRTC_PING_WDOG		0x04
+#define IMX_SIP_SRTC_SET_TIMEOUT_WDOG	0x05
+#define IMX_SIP_SRTC_GET_WDOG_STAT	0x06
+#define IMX_SIP_SRTC_SET_PRETIME_WDOG	0x07
+
+#if defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX)
+int imx_srtc_handler(uint32_t smc_fid, void *handle, u_register_t x1,
+	u_register_t x2, u_register_t x3, u_register_t x4);
+#endif
+
+#endif
diff --git a/plat/imx/common/srtc.c b/plat/imx/common/srtc.c
new file mode 100644
index 0000000..dc653c9
--- /dev/null
+++ b/plat/imx/common/srtc.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <std_svc.h>
+#include <platform_def.h>
+#include <sci/sci.h>
+#include <runtime_svc.h>
+#include <imx_sip.h>
+
+static int imx_srtc_set_time(uint32_t year_mon, unsigned long day_hour, unsigned long min_sec)
+{
+	return sc_timer_set_rtc_time(ipc_handle,
+		year_mon >> 16, year_mon & 0xffff,
+		day_hour >> 16, day_hour & 0xffff,
+		min_sec >> 16, min_sec & 0xffff);
+}
+
+static int imx_srtc_set_wdog_action(uint32_t x2)
+{
+	sc_rm_pt_t secure_part;
+	sc_err_t err;
+
+	err = sc_rm_get_partition(ipc_handle, &secure_part);
+	if (err)
+		return err;
+
+	err = sc_timer_set_wdog_action(ipc_handle, secure_part, x2);
+
+	return err;
+}
+
+int imx_srtc_handler(uint32_t smc_fid,
+		    void *handle,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    u_register_t x4)
+{
+	int ret;
+	sc_timer_wdog_time_t timeout, max_timeout, remaining;
+
+	switch(x1) {
+	case IMX_SIP_SRTC_SET_TIME:
+		ret = imx_srtc_set_time(x2, x3, x4);
+		break;
+	case IMX_SIP_SRTC_START_WDOG:
+		ret = sc_timer_start_wdog(ipc_handle, !!x2);
+		break;
+	case IMX_SIP_SRTC_STOP_WDOG:
+		ret = sc_timer_stop_wdog(ipc_handle);
+		break;
+	case IMX_SIP_SRTC_SET_WDOG_ACT:
+		ret = imx_srtc_set_wdog_action(x2);
+		break;
+	case IMX_SIP_SRTC_PING_WDOG:
+		ret = sc_timer_ping_wdog(ipc_handle);
+		break;
+	case IMX_SIP_SRTC_SET_TIMEOUT_WDOG:
+		ret = sc_timer_set_wdog_timeout(ipc_handle, x2);
+		break;
+	case IMX_SIP_SRTC_SET_PRETIME_WDOG:
+		ret = sc_timer_set_wdog_pre_timeout(ipc_handle, x2);
+		break;
+	case IMX_SIP_SRTC_GET_WDOG_STAT:
+		ret = sc_timer_get_wdog_status(ipc_handle, &timeout,
+						&max_timeout, &remaining);
+		SMC_RET4(handle, ret, timeout, max_timeout, remaining);
+	default:
+		ret = SMC_UNK;
+	}
+
+	SMC_RET1(handle, ret);
+}
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index ce84e2b..62c8cdc 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -22,6 +22,8 @@
 				plat/imx/imx8qm/imx8qm_psci.c		\
 				plat/imx/common/imx8_topology.c		\
 				plat/imx/common/imx8_psci.c		\
+				plat/imx/common/srtc.c			\
+				plat/imx/common/imx8_sip_svc.c		\
 				lib/xlat_tables/aarch64/xlat_tables.c		\
 				lib/xlat_tables/xlat_tables_common.c		\
 				lib/cpus/aarch64/cortex_a53.S			\
diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk
index 02559b4..a747796 100644
--- a/plat/imx/imx8qx/platform.mk
+++ b/plat/imx/imx8qx/platform.mk
@@ -21,6 +21,8 @@
 				plat/imx/imx8qx/imx8qx_psci.c		\
 				plat/imx/common/imx8_topology.c		\
 				plat/imx/common/imx8_psci.c		\
+				plat/imx/common/srtc.c			\
+				plat/imx/common/imx8_sip_svc.c		\
 				plat/common/plat_psci_common.c		\
 				lib/xlat_tables/xlat_tables_common.c	\
 				lib/xlat_tables/aarch64/xlat_tables.c	\