From: Emanuele Ghidoli <emanuele.ghid...@toradex.com>

AM62x SoC is available in multiple variant with a different
amount of CPU cores (Cortex-A) available, AM62x1, AM62x2, AM62x4
have respectively 1, 2 or 4 cores.

Update the FDT with the actual core count as read from the SoC registers,
with that change is possible to have a single dts/dtb file handling
the different variant at runtime.

A similar approach is implemented for example on i.MX8 and STM32MP1 SoC.

Signed-off-by: Emanuele Ghidoli <emanuele.ghid...@toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolc...@toradex.com>
---
 arch/arm/mach-k3/common.c | 48 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index f86ccaedc94f..5ee1851e3aaa 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -431,10 +431,58 @@ int fdt_fixup_msmc_ram(void *blob, char *parent_path, 
char *node_name)
 }
 
 #if defined(CONFIG_OF_SYSTEM_SETUP)
+static int fdt_del_node_path(void *blob, const char *path)
+{
+       int rc;
+       int nodeoff;
+
+       nodeoff = fdt_path_offset(blob, path);
+       if (nodeoff < 0)
+               return 0; /* Not found, skip it */
+
+       rc = fdt_del_node(blob, nodeoff);
+       if (rc < 0)
+               printf("Unable to delete node %s, err=%s\n", path, 
fdt_strerror(rc));
+       else
+               debug("Deleted node %s\n", path);
+       return rc;
+}
+
+static void fdt_fixup_cores_nodes_am625(void *blob, int core_nr)
+{
+       char node_path[32];
+
+       if (core_nr < 1)
+               return;
+
+       for (; core_nr < 4; core_nr++) {
+               snprintf(node_path, sizeof(node_path), "/cpus/cpu@%d", core_nr);
+               fdt_del_node_path(blob, node_path);
+               snprintf(node_path, sizeof(node_path), 
"/cpus/cpu-map/cluster0/core%d", core_nr);
+               fdt_del_node_path(blob, node_path);
+               snprintf(node_path, sizeof(node_path), 
"/bus@f0000/watchdog@e0%d0000", core_nr);
+               fdt_del_node_path(blob, node_path);
+       }
+}
+
+static int k3_get_core_nr(void)
+{
+#if defined(CONFIG_SOC_K3_AM625)
+       u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
+
+       return (full_devid & JTAG_DEV_CORE_NR_MASK) >> JTAG_DEV_CORE_NR_SHIFT;
+#else
+       return -1;
+#endif
+}
+
 int ft_system_setup(void *blob, struct bd_info *bd)
 {
        int ret = 0;
 
+       if (IS_ENABLED(CONFIG_SOC_K3_AM625))
+               fdt_fixup_cores_nodes_am625(blob, k3_get_core_nr());
+
        if (IS_ENABLED(CONFIG_SOC_K3_J721S2) ||
            IS_ENABLED(CONFIG_SOC_K3_AM654) ||
            IS_ENABLED(CONFIG_SOC_K3_J721E)) {
-- 
2.25.1

Reply via email to