arm: mach-k3: am642: Shut down R5 core after ATF startup on A53
authorSuman Anna <s-anna@ti.com>
Fri, 23 Apr 2021 16:27:38 +0000 (11:27 -0500)
committerLokesh Vutla <lokeshvutla@ti.com>
Wed, 12 May 2021 10:57:57 +0000 (16:27 +0530)
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

index d09fc59..2b58a9f 100644 (file)
@@ -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