[PATCH] lib: utils/hsm: spacemit: wait for the PMU to take a wakeup request
Ahmed Fardi
ahmedfardi93 at gmail.com
Wed Nov 4 08:09:37 PST 2026
The PMU clears a hart's wakeup bit about 17 us after it is written. A
second write before that replaces the pending request, so harts started
back to back may never wake up (on a BPI-F3, harts 4-6 stayed off).
Poll for the bit to clear, with a 1 ms timeout.
Signed-off-by: Ahmed Fardi <ahmedfardi93 at gmail.com>
---
Tested on a Banana Pi BPI-F3 (K1) with OP-TEE starting harts 1-7 back to
back: 5 of 8 harts came up before, 8 of 8 with this change. That test ran
on OpenSBI 1.8; this patch is the same change applied to current master.
lib/utils/hsm/fdt_hsm_spacemit.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/lib/utils/hsm/fdt_hsm_spacemit.c b/lib/utils/hsm/fdt_hsm_spacemit.c
index 4f76b99e..3ccb17db 100644
--- a/lib/utils/hsm/fdt_hsm_spacemit.c
+++ b/lib/utils/hsm/fdt_hsm_spacemit.c
@@ -11,6 +11,7 @@
#include <sbi/riscv_io.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_hsm.h>
+#include <sbi/sbi_timer.h>
#include <spacemit/common.h>
#include <spacemit/k1.h>
#include <spacemit/k3.h>
@@ -53,15 +54,27 @@ static inline void spacemit_k1_set_cpu_power(u32 hartid, bool enable)
writel(value, cpu_idle_base);
}
-static void spacemit_k1_wakeup_cpu(u32 mpidr)
+#define SPACEMIT_K1_WAKEUP_TIMEOUT_US 1000
+
+static int spacemit_k1_wakeup_cpu(u32 mpidr)
{
unsigned int *cpu_reset_base;
unsigned int cur_hartid = current_hartid();
+ unsigned int us;
cpu_reset_base =
(unsigned int *)(unsigned long)k1_cpu_wakeup_reg[cur_hartid];
writel(1 << mpidr, cpu_reset_base);
+
+ /* Wait for the PMU to take the request: a new write would replace it */
+ for (us = 0; us < SPACEMIT_K1_WAKEUP_TIMEOUT_US; us++) {
+ if (!(readl(cpu_reset_base) & (1 << mpidr)))
+ return 0;
+ sbi_timer_udelay(1);
+ }
+
+ return SBI_ETIMEDOUT;
}
static void spacemit_k1_assert_cpu(void)
@@ -78,9 +91,8 @@ static void spacemit_k1_deassert_cpu(unsigned int hartid)
static int spacemit_k1_hart_start(unsigned int hartid, unsigned long saddr)
{
spacemit_k1_deassert_cpu(hartid);
- spacemit_k1_wakeup_cpu(hartid);
- return 0;
+ return spacemit_k1_wakeup_cpu(hartid);
}
/*
--
2.53.0
More information about the opensbi
mailing list