plat: imx8m: Add basic rdc module init driver

Add the basic support for RDC init/config driver,
this module driver can be enhanced more if necessary.

Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Change-Id: I290dc378d0d85671435f9de46d5aa790b4e006c8
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index 63d9223..c3cd0d0 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -24,6 +24,7 @@
 #include <gpc.h>
 #include <imx_aipstz.h>
 #include <imx_uart.h>
+#include <imx_rdc.h>
 #include <imx8m_caam.h>
 #include <plat_imx8.h>
 
@@ -41,6 +42,18 @@
 	{0},
 };
 
+static const struct imx_rdc_cfg rdc[] = {
+	/* Master domain assignment */
+	RDC_MDAn(0x1, DID1),
+
+	/* peripherals domain permission */
+
+	/* memory region */
+
+	/* Sentinel */
+	{0},
+};
+
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
 
@@ -94,6 +107,8 @@
 
 	imx_aipstz_init(aipstz);
 
+	imx_rdc_init(rdc);
+
 	imx8m_caam_init();
 
 	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index c28463b..6d32dbb 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -20,6 +20,7 @@
 BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
+				plat/imx/imx8m/imx_rdc.c			\
 				plat/imx/imx8m/imx8m_caam.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
 				plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c	\
diff --git a/plat/imx/imx8m/imx_rdc.c b/plat/imx/imx8m/imx_rdc.c
new file mode 100644
index 0000000..85de191
--- /dev/null
+++ b/plat/imx/imx8m/imx_rdc.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019, NXP. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include <imx_rdc.h>
+
+void imx_rdc_init(const struct imx_rdc_cfg *rdc_cfg)
+{
+	const struct imx_rdc_cfg *rdc = rdc_cfg;
+
+	while (rdc->type != RDC_INVALID) {
+		switch (rdc->type) {
+		case RDC_MDA:
+			/* MDA config */
+			mmio_write_32(MDAn(rdc->index), rdc->setting.rdc_mda);
+			break;
+		case RDC_PDAP:
+			/* peripheral access permission config */
+			mmio_write_32(PDAPn(rdc->index), rdc->setting.rdc_pdap);
+			break;
+		case RDC_MEM_REGION:
+			/* memory region access permission config */
+			mmio_write_32(MRSAn(rdc->index), rdc->setting.rdc_mem_region[0]);
+			mmio_write_32(MREAn(rdc->index), rdc->setting.rdc_mem_region[1]);
+			mmio_write_32(MRCn(rdc->index), rdc->setting.rdc_mem_region[2]);
+			break;
+		default:
+			break;
+		}
+
+		rdc++;
+	}
+}
diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h
new file mode 100644
index 0000000..6be8550
--- /dev/null
+++ b/plat/imx/imx8m/include/imx_rdc.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2019, NXP. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_RDC_H
+#define IMX_RDC_H
+
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+#define MDAn(x)		(IMX_RDC_BASE + 0x200 + (x) * 4)
+#define PDAPn(x)	(IMX_RDC_BASE + 0x400 + (x) * 4)
+#define MRSAn(x)	(IMX_RDC_BASE + 0x800 + (x) * 4)
+#define MREAn(x)	(IMX_RDC_BASE + 0x804 + (x) * 4)
+#define MRCn(x)		(IMX_RDC_BASE + 0x808 + (x) * 4)
+
+#define LCK		BIT(31)
+#define SREQ		BIT(30)
+#define ENA		BIT(30)
+
+#define DID0		U(0x0)
+#define DID1		U(0x1)
+#define DID2		U(0x2)
+#define DID3		U(0x3)
+
+#define D3R		BIT(7)
+#define D3W		BIT(6)
+#define D2R		BIT(5)
+#define D2W		BIT(4)
+#define D1R		BIT(3)
+#define D1W		BIT(2)
+#define D0R		BIT(1)
+#define D0W		BIT(0)
+
+union rdc_setting {
+	uint32_t rdc_mda; /* Master Domain Assignment */
+	uint32_t rdc_pdap; /* Peripheral Domain Access Permissions */
+	uint32_t rdc_mem_region[3]; /* Memory Region Access Control */
+};
+
+enum rdc_type {
+	RDC_INVALID,
+	RDC_MDA,
+	RDC_PDAP,
+	RDC_MEM_REGION,
+};
+
+struct imx_rdc_cfg {
+	enum rdc_type type; /* config type Master, Peripheral or Memory region */
+	int index;
+	union rdc_setting setting;
+};
+
+#define RDC_MDAn(i, mda)	\
+	{RDC_MDA, (i), .setting.rdc_mda = (mda), }
+#define RDC_PDAPn(i, pdap)	\
+	{RDC_PDAP, (i), .setting.rdc_pdap = (pdap), }
+
+#define RDC_MEM_REGIONn(i, msa, mea, mrc)	\
+	{ RDC_MEM_REGION, (i), 			\
+	  .setting.rdc_mem_region[0] = (msa),	\
+	  .setting.rdc_mem_region[1] = (mea),	\
+	  .setting.rdc_mem_region[2] = (mrc),	\
+	}
+
+void imx_rdc_init(const struct imx_rdc_cfg *cfg);
+
+#endif /* IMX_RDC_H */
+