diff options
author | Sin Hui Kho <sin.hui.kho@intel.com> | 2023-03-02 12:25:22 +0800 |
---|---|---|
committer | BenjaminLimJL <jit.loon.lim@intel.com> | 2023-03-07 10:02:29 +0800 |
commit | 6d890139236cc4b46dcd0181abe19b5eb56b2c6a (patch) | |
tree | 0739b8415977f06387ebc946902cb03d2e21668a | |
parent | f2d791e2153af5902d0951c08e7d5672fb68a0c9 (diff) | |
download | u-boot-socfpga-6d890139236cc4b46dcd0181abe19b5eb56b2c6a.tar.gz |
HSD #14015872909: arch: arm: soc64: Put CPU0 to wait for ATF when only CPU0 power off/on
There is a use case where kernel requested ATF to power off/on only CPU0.
However, after ATF power off/on CPU0, CPU0 did not back into the state
to wait for ATF. Instead, CPU0 continue to reentry SPL boot sequence
because CPU0 is master/primary core. This causing the system reboot from
SPL again, while the slave core still in kernel.
To resolve this, ATF is set the boot scratch register 8 bit 17 whenever it
is a request from kernel to power off/on only CPU0. So, if this boot
scratch bit is set, CPU 0 will be able to put into a state to wait for ATF.
Signed-off-by: Sin Hui Kho <sin.hui.kho@intel.com>
-rw-r--r-- | arch/arm/mach-socfpga/lowlevel_init_soc64.S | 16 | ||||
-rw-r--r-- | include/configs/socfpga_soc64_common.h | 4 |
2 files changed, 20 insertions, 0 deletions
diff --git a/arch/arm/mach-socfpga/lowlevel_init_soc64.S b/arch/arm/mach-socfpga/lowlevel_init_soc64.S index efdd3855c0..b75569e7a1 100644 --- a/arch/arm/mach-socfpga/lowlevel_init_soc64.S +++ b/arch/arm/mach-socfpga/lowlevel_init_soc64.S @@ -64,6 +64,14 @@ skipwarmreset: * and latest status in next reset. */ + /* Check if it is a master core off/on from kernel using boot scratch + * cold register 8 bit 17. This bit is set by ATF. + */ + ldr x4, =BOOT_SCRATCH_COLD8 + ldr x5, [x4] + and x6, x5, #0x20000 + cbnz x6, wait_for_atf_master + /* Retrieve mpurststat register in reset manager */ ldr x4, =SOCFPGA_RSTMGR_ADDRESS ldr w5, [x4, #0x04] @@ -104,6 +112,14 @@ wait_for_atf: slave_wait_atf: branch_if_slave x0, wait_for_atf +wait_for_atf_master: + ldr x4, =CPU_RELEASE_ADDR + ldr x5, [x4] + cbz x5, master_wait_atf + br x5 +master_wait_atf: + branch_if_master x0, wait_for_atf_master + master_cpu: #else branch_if_slave x0, 1f diff --git a/include/configs/socfpga_soc64_common.h b/include/configs/socfpga_soc64_common.h index 0c5e193d31..c9e3001cea 100644 --- a/include/configs/socfpga_soc64_common.h +++ b/include/configs/socfpga_soc64_common.h @@ -16,6 +16,10 @@ */ /* sysmgr.boot_scratch_cold4 & 5 (64bit) will be used for PSCI_CPU_ON call */ #define CPU_RELEASE_ADDR 0xFFD12210 +/* sysmgr.boot_scratch_cold8 bit 17 (1bit) will be used to check whether CPU0 + * is being powered off/on from kernel + */ +#define BOOT_SCRATCH_COLD8 0xFFD12220 /* * sysmgr.boot_scratch_cold6 & 7 (64bit) will be used by master CPU to |