feat(zynqmp): dedicate console for boot and runtime

Introduce a build-time parameter (CONSOLE_RUNTIME) to select
separate runtime console options. For boot-time console, remove
the runtime flag and add a boot/crash flag. Additionally,
introduce an RT_CONSOLE_IS macro to check different UART types.

Implement a common function, console_runtime_init(), to initialize
the runtime console. Ensure that all platforms have access to
this feature.

The current implementation utilizes a single console for boot,
crash, and runtime. Make sure that the dedicated console integrates
into runtime and crash scenarios.

Change-Id: I32913dede3d87109e54d179e7d99f45c33b9097b
Signed-off-by: Prasad Kummari <prasad.kummari@amd.com>
Signed-off-by: Maheedhar Bollapalli <MaheedharSai.Bollapalli@amd.com>
diff --git a/plat/xilinx/common/include/plat_console.h b/plat/xilinx/common/include/plat_console.h
index 0f8320e..b38f347 100644
--- a/plat/xilinx/common/include/plat_console.h
+++ b/plat/xilinx/common/include/plat_console.h
@@ -15,6 +15,12 @@
 #define DT_UART_COMPAT	"arm,pl011"
 #endif
 
+/*Default console type is either CADENCE0 or CADENCE1 or PL011_0 or PL011_1
+ * Debug console type is DCC
+ **/
+#define PLAT_XLNX_CONSOLE_TYPE_DEFAULT 0
+#define PLAT_XLNX_CONSOLE_TYPE_DEBUG   1
+
 typedef struct dt_uart_info_s {
 	char compatible[30];
 	uintptr_t base;
@@ -24,4 +30,8 @@
 
 void setup_console(void);
 
+#if defined(CONSOLE_RUNTIME)
+void console_runtime_init(void);
+#endif
+
 #endif /* PLAT_DT_UART_H */
diff --git a/plat/xilinx/common/plat_console.c b/plat/xilinx/common/plat_console.c
index 610c84f..72fd881 100644
--- a/plat/xilinx/common/plat_console.c
+++ b/plat/xilinx/common/plat_console.c
@@ -25,7 +25,51 @@
 
 static console_t boot_console;
 
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE)) || \
+	defined(CONSOLE_RUNTIME)
+/**
+ * register_console() - Registers the runtime uart with console list.
+ * @uart_base: UART base address
+ * @clock: UART clock.
+ * @baud_rate: UART buad rate
+ * @console: Pointer to the console information structure.
+ * @flags: console flags.
+ */
+static void register_console(uintptr_t uart_base, uint32_t clock,
+		uint32_t baud_rate, console_t *console,
+		uint32_t flags, uint8_t console_type)
+{
+	int32_t rc = 0;
+
+	if (console_type == PLAT_XLNX_CONSOLE_TYPE_DEFAULT) {
+#if defined(PLAT_zynqmp)
+		rc = console_cdns_register(uart_base,
+				clock,
+				baud_rate,
+				console);
+#elif defined(PLAT_versal) || defined(PLAT_versal_net) || defined(PLAT_versal2)
+		rc = console_pl011_register(uart_base,
+				clock,
+				baud_rate,
+				console);
+#endif
+	} else if (console_type == PLAT_XLNX_CONSOLE_TYPE_DEBUG) {
+		rc = console_dcc_register(console);
+	} else {
+		INFO("Invalid console type\n");
+	}
+
+	if (rc == 0) {
+		panic();
+	}
+
+	console_set_scope(console, flags);
+}
+#endif
+
 #if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+
+static console_t dt_console;
 /**
  * get_baudrate() - Get the baudrate form DTB.
  * @dtb: Address of the Device Tree Blob (DTB).
@@ -222,38 +266,6 @@
 }
 
 /**
- * register_console() - Registers the runtime uart with console list.
- * @uart_base: UART base address
- * @clock: UART clock.
- * @baud_rate: UART buad rate
- * @console: Pointer to the console information structure.
- * @flags: console flags.
- */
-static void register_console(uintptr_t uart_base, uint32_t clock,
-			     uint32_t baud_rate, console_t *console,
-			     uint32_t flags)
-{
-	int32_t rc;
-
-#if defined(PLAT_zynqmp)
-	rc = console_cdns_register(uart_base,
-				   clock,
-				   baud_rate,
-				   console);
-#else
-	rc = console_pl011_register(uart_base,
-				    clock,
-				    baud_rate,
-				    console);
-#endif
-	if (rc == 0) {
-		panic();
-	}
-
-	console_set_scope(console, flags);
-}
-
-/**
  * parse_uart_info() - Parse UART information from Device Tree Blob.
  * @uart_info: Pointer to the UART information structure.
  *
@@ -281,7 +293,8 @@
 {
 	register_console(uart_info->base, clock, uart_info->baud_rate,
 			console,  CONSOLE_FLAG_BOOT |
-			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH,
+			PLAT_XLNX_CONSOLE_TYPE_DEFAULT);
 	console_end(end_console);
 	INFO("DTB console setup\n");
 }
@@ -314,7 +327,6 @@
 			  uint32_t clock)
 {
 	int32_t rc = 0;
-	static console_t dt_console;
 
 	/* Parse UART information from Device Tree Blob (DTB) */
 	rc = parse_uart_info(uart_info);
@@ -327,6 +339,11 @@
 		goto error;
 	}
 
+	rc = check_fdt_uart_info(uart_info);
+	if (rc < 0) {
+		goto error;
+	}
+
 	if (strncmp(uart_info->compatible, DT_UART_COMPAT,
 		    strlen(DT_UART_COMPAT)) == 0) {
 		handle_dt_console(uart_info, &dt_console, clock, console);
@@ -342,6 +359,64 @@
 }
 #endif
 
+#if defined(CONSOLE_RUNTIME)
+void console_runtime_init(void)
+{
+	uint32_t uart_clk = get_uart_clk();
+	static console_t runtime_console;
+	uintptr_t rt_uart_base = 0;
+	uint32_t buad_rate = 0;
+	static dt_uart_info_t dt_info = {0};
+
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+	console_t *console = &dt_console;
+#else
+	console_t *console = &boot_console;
+#endif
+
+#if (RT_CONSOLE_IS(dtb) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
+	uint32_t rc = parse_uart_info(&dt_info);
+
+	if (rc < 0) {
+		goto error;
+	} else {
+		rt_uart_base = dt_info.base;
+		buad_rate = dt_info.baud_rate;
+	}
+#elif defined(PLAT_zynqmp)
+	if (RT_CONSOLE_IS(cadence) || (RT_CONSOLE_IS(cadence1))) {
+		rt_uart_base = (uintptr_t)RT_UART_BASE;
+		buad_rate = (uint32_t)UART_BAUDRATE;
+	}
+#else
+	if (RT_CONSOLE_IS(pl011) || (RT_CONSOLE_IS(pl011_1))) {
+		rt_uart_base = (uintptr_t)RT_UART_BASE;
+		buad_rate = (uint32_t)UART_BAUDRATE;
+	}
+#endif
+	/*skip console registration if runtime and boot console are same */
+	if (console->base != rt_uart_base) {
+		/* Remove runtime flag from boot console */
+		console_set_scope(console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH);
+
+		register_console(rt_uart_base, uart_clk, buad_rate, &runtime_console,
+				 CONSOLE_FLAG_RUNTIME, PLAT_XLNX_CONSOLE_TYPE_DEFAULT);
+		INFO("Successfully initialized runtime console\n");
+	}
+
+#if (RT_CONSOLE_IS(dtb) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
+error:
+	if (rc < 0) {
+		ERROR("Failed to parse uart info in runtime console\n");
+	}
+#endif
+}
+#endif
+
 void setup_console(void)
 {
 	int32_t rc;
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 50d4240..a6d270c 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -191,6 +191,10 @@
 #endif
 
 	custom_runtime_setup();
+
+#if defined(CONSOLE_RUNTIME)
+	console_runtime_init();
+#endif
 }
 
 /*
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index d715ce2..ef72c2c 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -17,6 +17,15 @@
 
 #define CONSOLE_IS(con)	(ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
 
+/* Runtime console */
+#define RT_CONSOLE_ID_cadence	1
+#define RT_CONSOLE_ID_cadence0	1
+#define RT_CONSOLE_ID_cadence1	2
+#define RT_CONSOLE_ID_dcc	3
+#define RT_CONSOLE_ID_dtb	4
+
+#define RT_CONSOLE_IS(con)	(RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
 /* Default counter frequency */
 #define ZYNQMP_DEFAULT_COUNTER_FREQ	0U
 
@@ -152,6 +161,17 @@
 # error "invalid ZYNQMP_CONSOLE"
 #endif
 
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(cadence) || RT_CONSOLE_IS(dcc) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE	ZYNQMP_UART0_BASE
+#elif RT_CONSOLE_IS(cadence1)
+# define RT_UART_BASE	ZYNQMP_UART1_BASE
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
 /* Must be non zero */
 #define UART_BAUDRATE		115200
 
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 9fdc649..92c9d1f 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -117,6 +117,20 @@
 endif
 $(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE}))
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= cadence
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},cadence cadence0 cadence1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 # Build PM code as a Library
 include plat/xilinx/zynqmp/libpm.mk