]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
arm64: zynqmp: Print an error for split to lock mode switch
authorPadmarao Begari <padmarao.begari@amd.com>
Mon, 30 Sep 2024 04:38:13 +0000 (10:08 +0530)
committerMichal Simek <michal.simek@amd.com>
Fri, 25 Oct 2024 12:10:31 +0000 (14:10 +0200)
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>
arch/arm/mach-zynqmp/cpu.c
arch/arm/mach-zynqmp/include/mach/sys_proto.h
arch/arm/mach-zynqmp/mp.c

index 24fd57512163955962d879a60ab2856402c3d8eb..5db99e2a73a1201a7b4fae0eaa41edd98e3c56a3 100644 (file)
@@ -115,9 +115,19 @@ u64 get_page_table_size(void)
 #if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP)
 void tcm_init(u8 mode)
 {
-       puts("WARNING: Initializing TCM overwrites TCM content\n");
-       initialize_tcm(mode);
-       memset((void *)ZYNQMP_TCM_BASE_ADDR, 0, ZYNQMP_TCM_SIZE);
+       int ret;
+
+       ret = check_tcm_mode(mode);
+       if (!ret) {
+               puts("WARNING: Initializing TCM overwrites TCM content\n");
+               initialize_tcm(mode);
+               memset((void *)ZYNQMP_TCM_BASE_ADDR, 0, ZYNQMP_TCM_SIZE);
+       }
+
+       if (ret == -EACCES)
+               printf("ERROR: Split to lockstep mode required reset/disable cpu\n");
+
+       /* Ignore if ret is -EAGAIN, trying to initialize same mode again */
 }
 #endif
 
index 15b69e777124d1ccd560a68e03fa01a5305fff44..b3396db28f0b9d4bb1fcf11bd3287401bcf12b1e 100644 (file)
@@ -48,6 +48,7 @@ enum {
 
 unsigned int zynqmp_get_silicon_version(void);
 
+int check_tcm_mode(bool mode);
 void initialize_tcm(bool mode);
 void mem_map_fill(void);
 #if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP)
index 9b46a25a1cbe970f1b6e01e2ab2f688549c59003..6e6da8008f402c28cb646980429892e31026b898 100644 (file)
@@ -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 @@ void initialize_tcm(bool mode)
        }
 }
 
+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;