arm64: zynqmp: Print an error for split to lock mode switch

The zynqmp tcminit crashes the U-Boot when switching from
r5-mode "split" to "lockstep" instead it should throw an error.
When cpu is enabled, the check_tcm_mode() function checks
if the previous mode is "split", switch mode is "lockstep" then
it returns the error code and the initialize_tcm() function is not
updating the global control register of the RPU instead it prints
the error message. When cpu is disabled, the check_tcm_mode()
function returns the success code for switch split to lockstep mode.

Signed-off-by: Padmarao Begari <padmarao.begari@amd.com>
Link: https://lore.kernel.org/r/20240930043814.530181-2-padmarao.begari@amd.com
Signed-off-by: Michal Simek <michal.simek@amd.com>
diff --git a/arch/arm/mach-zynqmp/mp.c b/arch/arm/mach-zynqmp/mp.c
index 9b46a25..6e6da80 100644
--- a/arch/arm/mach-zynqmp/mp.c
+++ b/arch/arm/mach-zynqmp/mp.c
@@ -12,7 +12,9 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
+#include <linux/bitfield.h>
 #include <linux/delay.h>
+#include <linux/errno.h>
 #include <linux/string.h>
 
 #define LOCK		0
@@ -264,6 +266,28 @@
 	}
 }
 
+int check_tcm_mode(bool mode)
+{
+	u32 tmp, cpu_state;
+	bool mode_prev;
+
+	tmp = readl(&rpu_base->rpu_glbl_ctrl);
+	mode_prev = FIELD_GET(ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK, tmp);
+
+	tmp = readl(&crlapb_base->rst_lpd_top);
+	cpu_state = FIELD_GET(ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK |
+			      ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK, tmp);
+	cpu_state = cpu_state ? false : true;
+
+	if ((mode_prev == SPLIT && mode == LOCK) && cpu_state)
+		return -EACCES;
+
+	if (mode_prev == mode)
+		return -EAGAIN;
+
+	return 0;
+}
+
 static void mark_r5_used(u32 nr, u8 mode)
 {
 	u32 mask = 0;