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
