diff mbox series

[07/17] arm: mach-k3: am642: Shut down R5 core after ATF startup on A53

Message ID 20210423162748.1952-8-d-gerlach@ti.com
State Accepted
Commit 078332cee36fcb6562d2ef61913861b0a0f06b56
Delegated to: Lokesh Vutla
Headers show
Series arm: mach-k3: Initial Support for Texas Instruments AM642 Platform | expand

Commit Message

Dave Gerlach April 23, 2021, 4:27 p.m. UTC
From: Suman Anna <s-anna@ti.com>

The AM642 SoCs use the Main R5FSS0 as a boot processor, and runs
the R5 SPL that performs the initialization of the System Controller
processor and starting the Arm Trusted Firmware (ATF) on the Arm
Cortex A53 cluster. The Core0 serves as this boot processor and is
parked in WFE after all the initialization. Core1 does not directly
participate in the boot flow, and is simply parked in a WFI.

Power down these R5 cores (and the associated RTI timer resources
that were indirectly powered up) after starting up ATF on A53 by
using the appropriate SYSFW API in release_resources_for_core_shutdown().
This allows these Main R5F cores to be further controlled from the
A53 to run regular applications.

Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 arch/arm/mach-k3/am642_init.c | 51 +++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
diff mbox series

Patch

diff --git a/arch/arm/mach-k3/am642_init.c b/arch/arm/mach-k3/am642_init.c
index adae9fbbb8cc..8931aaabf2f9 100644
--- a/arch/arm/mach-k3/am642_init.c
+++ b/arch/arm/mach-k3/am642_init.c
@@ -230,3 +230,54 @@  u32 spl_boot_device(void)
 		return __get_backup_bootmedia(devstat);
 }
 #endif
+
+#if defined(CONFIG_SYS_K3_SPL_ATF)
+
+#define AM64X_DEV_RTI8			127
+#define AM64X_DEV_RTI9			128
+#define AM64X_DEV_R5FSS0_CORE0		121
+#define AM64X_DEV_R5FSS0_CORE1		122
+
+void release_resources_for_core_shutdown(void)
+{
+	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
+	struct ti_sci_dev_ops *dev_ops = &ti_sci->ops.dev_ops;
+	struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops;
+	int ret;
+	u32 i;
+
+	const u32 put_device_ids[] = {
+		AM64X_DEV_RTI9,
+		AM64X_DEV_RTI8,
+	};
+
+	/* Iterate through list of devices to put (shutdown) */
+	for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) {
+		u32 id = put_device_ids[i];
+
+		ret = dev_ops->put_device(ti_sci, id);
+		if (ret)
+			panic("Failed to put device %u (%d)\n", id, ret);
+	}
+
+	const u32 put_core_ids[] = {
+		AM64X_DEV_R5FSS0_CORE1,
+		AM64X_DEV_R5FSS0_CORE0, /* Handle CPU0 after CPU1 */
+	};
+
+	/* Iterate through list of cores to put (shutdown) */
+	for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) {
+		u32 id = put_core_ids[i];
+
+		/*
+		 * Queue up the core shutdown request. Note that this call
+		 * needs to be followed up by an actual invocation of an WFE
+		 * or WFI CPU instruction.
+		 */
+		ret = proc_ops->proc_shutdown_no_wait(ti_sci, id);
+		if (ret)
+			panic("Failed sending core %u shutdown message (%d)\n",
+			      id, ret);
+	}
+}
+#endif