plat: imx8m: Add the basic support for imx8mm

The i.MX8M Mini is new SOC of the i.MX8M family. it is
focused on delivering the latest and greatest video and
audio experience combining state-of-the-art media-specific
features with high-performance processing while optimized
for lowest power consumption. The i.MX 8M Mini Media Applications
Processor is  14nm FinFET product of the growing i.MX8M family
targeting the consumer & industrial market. It is built in 14LPP
to achieve both high performance and low power consumption
and relies on a powerful fully coherent core complex based on
a quad Cortex-A53 cluster with video and graphics accelerators

this patch add the basic support for i.MX8MM.

Signed-off-by: Jacky Bai <ping.bai@nxp.com>
diff --git a/plat/imx/imx8m/imx8mm/gpc.c b/plat/imx/imx8m/imx8mm/gpc.c
new file mode 100644
index 0000000..ab59292
--- /dev/null
+++ b/plat/imx/imx8m/imx8mm/gpc.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/smccc.h>
+#include <platform_def.h>
+#include <services/std_svc.h>
+
+#include <gpc.h>
+#include <imx_sip_svc.h>
+
+void imx_gpc_init(void)
+{
+	unsigned int val;
+	int i;
+
+	/* mask all the wakeup irq by default */
+	for (i = 0; i < 4; i++) {
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_A53 + i * 4, ~0x0);
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE1_A53 + i * 4, ~0x0);
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE2_A53 + i * 4, ~0x0);
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE3_A53 + i * 4, ~0x0);
+		mmio_write_32(IMX_GPC_BASE + IMR1_CORE0_M4 + i * 4, ~0x0);
+	}
+
+	val = mmio_read_32(IMX_GPC_BASE + LPCR_A53_BSC);
+	/* use GIC wake_request to wakeup C0~C3 from LPM */
+	val |= 0x30c00000;
+	/* clear the MASTER0 LPM handshake */
+	val &= ~(1 << 6);
+	mmio_write_32(IMX_GPC_BASE + LPCR_A53_BSC, val);
+
+	/* clear MASTER1 & MASTER2 mapping in CPU0(A53) */
+	mmio_clrbits_32(IMX_GPC_BASE + MST_CPU_MAPPING, (MASTER1_MAPPING |
+		MASTER2_MAPPING));
+
+	/* set all mix/PU in A53 domain */
+	mmio_write_32(IMX_GPC_BASE + PGC_CPU_0_1_MAPPING, 0xffff);
+
+	/*
+	 * Set the CORE & SCU power up timing:
+	 * SW = 0x1, SW2ISO = 0x1;
+	 * the CPU CORE and SCU power up timming counter
+	 * is drived  by 32K OSC, each domain's power up
+	 * latency is (SW + SW2ISO) / 32768
+	 */
+	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(0) + 0x4, 0x81);
+	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(1) + 0x4, 0x81);
+	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(2) + 0x4, 0x81);
+	mmio_write_32(IMX_GPC_BASE + COREx_PGC_PCR(3) + 0x4, 0x81);
+	mmio_write_32(IMX_GPC_BASE + PLAT_PGC_PCR + 0x4, 0x81);
+	mmio_write_32(IMX_GPC_BASE + PGC_SCU_TIMING,
+		      (0x59 << 10) | 0x5B | (0x2 << 20));
+
+	/* set DUMMY PDN/PUP ACK by default for A53 domain */
+	mmio_write_32(IMX_GPC_BASE + PGC_ACK_SEL_A53,
+		      A53_DUMMY_PUP_ACK | A53_DUMMY_PDN_ACK);
+
+	/* clear DSM by default */
+	val = mmio_read_32(IMX_GPC_BASE + SLPCR);
+	val &= ~SLPCR_EN_DSM;
+	/* enable the fast wakeup wait mode */
+	val |= SLPCR_A53_FASTWUP_WAIT_MODE;
+	/* clear the RBC */
+	val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT);
+	/* set the STBY_COUNT to 0x5, (128 * 30)us */
+	val &= ~(0x7 << SLPCR_STBY_COUNT_SHFT);
+	val |= (0x5 << SLPCR_STBY_COUNT_SHFT);
+	mmio_write_32(IMX_GPC_BASE + SLPCR, val);
+
+	/*
+	 * USB PHY power up needs to make sure RESET bit in SRC is clear,
+	 * otherwise, the PU power up bit in GPC will NOT self-cleared.
+	 * only need to do it once.
+	 */
+	mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
+	mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
+
+	/* enable all the power domain by default */
+	mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x3fcf);
+}