Some version of the AM64 processors have reduced CPU counts. To avoid
boot stalls while Linux tries to probe these missing CPUs use the
DEVICE_ID field in the JTAG_USER_ID register to know if we need to
remove these CPUs from the DT before booting into Linux.

Signed-off-by: Bryan Brattlof <[email protected]>
---
 arch/arm/mach-k3/am64x/Kconfig                |  1 +
 arch/arm/mach-k3/am64x/Makefile               |  1 +
 arch/arm/mach-k3/am64x/am642_fdt.c            | 36 +++++++++++++++++++++++++++
 arch/arm/mach-k3/include/mach/am64_hardware.h |  9 +++++++
 4 files changed, 47 insertions(+)

diff --git a/arch/arm/mach-k3/am64x/Kconfig b/arch/arm/mach-k3/am64x/Kconfig
index e8b7d54d7ac3..026a9403fcf9 100644
--- a/arch/arm/mach-k3/am64x/Kconfig
+++ b/arch/arm/mach-k3/am64x/Kconfig
@@ -16,6 +16,7 @@ config TARGET_AM642_A53_EVM
        imply BOARD
        imply SPL_BOARD
        imply TI_I2C_BOARD_DETECT
+       imply OF_SYSTEM_SETUP
 
 config TARGET_AM642_R5_EVM
        bool "TI K3 based AM642 EVM running on R5"
diff --git a/arch/arm/mach-k3/am64x/Makefile b/arch/arm/mach-k3/am64x/Makefile
index 053a82399993..9ef6d9bee098 100644
--- a/arch/arm/mach-k3/am64x/Makefile
+++ b/arch/arm/mach-k3/am64x/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier:     GPL-2.0+
 
+obj-$(CONFIG_OF_SYSTEM_SETUP) += am642_fdt.o
 obj-$(CONFIG_XPL_BUILD) += am642_init.o
 obj-y += boot.o
diff --git a/arch/arm/mach-k3/am64x/am642_fdt.c 
b/arch/arm/mach-k3/am64x/am642_fdt.c
new file mode 100644
index 000000000000..a8e6c946d584
--- /dev/null
+++ b/arch/arm/mach-k3/am64x/am642_fdt.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <asm/arch/k3-common-fdt.h>
+#include <asm/hardware.h>
+#include <fdt_support.h>
+
+static int fdt_fixup_a53_nodes(void *dt)
+{
+       int nr = k3_get_core_nr();
+       char path[32];
+
+       /* remove the fused out cpus */
+       for (; nr < 2; nr++) {
+               snprintf(path, sizeof(path), "/cpus/cpu@%d", nr);
+               fdt_del_node_path(dt, path);
+
+               /* remove the cpu from the cluster */
+               snprintf(path, sizeof(path), "/cpus/cpu-map/cluster0/core%d", 
nr);
+               fdt_del_node_path(dt, path);
+
+               /* remove the watchdog for the cpu */
+               snprintf(path, sizeof(path), "/bus@f0000/watchdog@e0%d0000", 
nr);
+               fdt_del_node_path(dt, path);
+       }
+
+       return 0;
+}
+
+int ft_system_setup(void *blob, struct bd_info *bd)
+{
+       fdt_fixup_a53_nodes(blob);
+       return fdt_fixup_reserved(blob);
+}
diff --git a/arch/arm/mach-k3/include/mach/am64_hardware.h 
b/arch/arm/mach-k3/include/mach/am64_hardware.h
index 7e33617151e1..53c05f44fbe9 100644
--- a/arch/arm/mach-k3/include/mach/am64_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am64_hardware.h
@@ -19,6 +19,8 @@
 #define CTRL_MMR0_BASE                                 0x43000000
 
 #define CTRLMMR_WKUP_JTAG_DEVICE_ID            (WKUP_CTRL_MMR0_BASE + 0x18)
+#define JTAG_DEV_CORE_NR_MASK                  GENMASK(23, 22)
+#define JTAG_DEV_CORE_NR_SHIFT                 22
 #define JTAG_DEV_SPEED_MASK                    GENMASK(10, 6)
 #define JTAG_DEV_SPEED_SHIFT                   6
 
@@ -89,3 +91,10 @@ static const u32 put_core_ids[] = {
 };
 
 #endif /* __ASM_ARCH_DRA8_HARDWARE_H */
+
+static inline int k3_get_core_nr(void)
+{
+       u32 devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
+
+       return (devid & JTAG_DEV_CORE_NR_MASK) >> JTAG_DEV_CORE_NR_SHIFT;
+}

-- 
2.55.0

Reply via email to