fix(imx8m): ensure domain permissions for the console

The commit d76f012ea8fc0 ("refactor(imx8m): replace magic number with
enum type") also hardcodes the domain permissions configuration for the
UARTs, causing a regression for any board using a boot console different
from UART2. Indeed, previously, the RDC_PDAP_UARTn registers were set to
the reset value (0xff), meaning all domains were enabled for read and
write access.

This patch fixes this regression by ensuring that the console always has
read/write access enabled for domain 0.

Tested on a i.MX8MN BSH SMM S2 PRO board.

Fixes: d76f012ea8fc0 ("refactor(imx8m): replace magic number with enum type")
Change-Id: I2670bf485372f32ef45cebb72a7694a9a800f417
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index f6e46eb..03edc6e 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -62,7 +62,7 @@
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M4, DID1),
 
@@ -164,14 +164,14 @@
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
-
-	imx_csu_init(csu_cfg);
-
 	if (console_base == 0U) {
 		console_base = imx8m_uart_get_base();
 	}
 
+	imx_rdc_init(rdc, console_base);
+
+	imx_csu_init(csu_cfg);
+
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index befa769..42d173e 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -48,7 +48,7 @@
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M7, DID1),
 
@@ -136,7 +136,11 @@
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	imx_rdc_init(rdc, console_base);
 
 	imx_csu_init(csu_cfg);
 
@@ -152,10 +156,6 @@
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	if (console_base == 0U) {
-		console_base = imx8m_uart_get_base();
-	}
-
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index ffad3d1..141c94b 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -49,7 +49,7 @@
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M7, DID1),
 
@@ -166,7 +166,11 @@
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	imx_rdc_init(rdc, console_base);
 
 	imx_csu_init(csu_cfg);
 
@@ -175,10 +179,6 @@
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	if (console_base == 0U) {
-		console_base = imx8m_uart_get_base();
-	}
-
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx_rdc.c b/plat/imx/imx8m/imx_rdc.c
index 85de191..de15956 100644
--- a/plat/imx/imx8m/imx_rdc.c
+++ b/plat/imx/imx8m/imx_rdc.c
@@ -4,13 +4,78 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
+
 #include <lib/mmio.h>
 
 #include <imx_rdc.h>
 
+struct imx_uart {
+	int index;
+	unsigned int uart_base;
+};
+
+static const struct imx_uart imx8m_uart_info[] = {
+	{	/* UART 1 */
+		.index = RDC_PDAP_UART1,
+		.uart_base = IMX_UART1_BASE,
+	}, {	/* UART 2 */
+		.index = RDC_PDAP_UART2,
+		.uart_base = IMX_UART2_BASE,
+	}, {	/* UART 3 */
+		.index = RDC_PDAP_UART3,
+		.uart_base = IMX_UART3_BASE,
+	}, {	/* UART 4 */
+		.index = RDC_PDAP_UART4,
+		.uart_base = IMX_UART4_BASE,
+	}
+};
+
+static int imx_rdc_uart_get_pdap_index(unsigned int uart_base)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) {
+		if (imx8m_uart_info[i].uart_base == uart_base) {
+			return imx8m_uart_info[i].index;
+		}
+	}
+
+	return -ENODEV;
+}
+
-void imx_rdc_init(const struct imx_rdc_cfg *rdc_cfg)
+static void imx_rdc_console_access_enable(struct imx_rdc_cfg *rdc_cfg,
+				   unsigned int console_base)
 {
-	const struct imx_rdc_cfg *rdc = rdc_cfg;
+	struct imx_rdc_cfg *rdc;
+	int console_pdap_index;
+
+	console_pdap_index = imx_rdc_uart_get_pdap_index(console_base);
+	if (console_pdap_index < 0) {
+		return;
+	}
+
+	for (rdc = rdc_cfg; rdc->type != RDC_INVALID; rdc++) {
+		if (rdc->type != RDC_PDAP || rdc->index != console_pdap_index) {
+			continue;
+		}
+
+		if (rdc->index == console_pdap_index &&
+		    rdc->setting.rdc_pdap == (D0R | D0W)) {
+			return;
+		}
+
+		if (rdc->index == console_pdap_index) {
+			rdc->setting.rdc_pdap = D0R | D0W;
+		}
+	}
+}
+
+void imx_rdc_init(struct imx_rdc_cfg *rdc_cfg, unsigned int console_base)
+{
+	struct imx_rdc_cfg *rdc = rdc_cfg;
+
+	imx_rdc_console_access_enable(rdc, console_base);
 
 	while (rdc->type != RDC_INVALID) {
 		switch (rdc->type) {
diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h
index a6e10a7..fbdcbf2 100644
--- a/plat/imx/imx8m/include/imx_rdc.h
+++ b/plat/imx/imx8m/include/imx_rdc.h
@@ -67,7 +67,7 @@
 	  .setting.rdc_mem_region[2] = (mrc),	\
 	}
 
-void imx_rdc_init(const struct imx_rdc_cfg *cfg);
+void imx_rdc_init(struct imx_rdc_cfg *cfg, unsigned int console_base);
 
 #endif /* IMX_RDC_H */