From 8f8c39315520acf2c3ba2e65d5e6ed887230011a Mon Sep 17 00:00:00 2001 From: Nick Hu Date: Mon, 20 Oct 2025 14:34:12 +0800 Subject: [PATCH] lib: utils/timer: Expose timer update function Exposing the ACLINT timer update APIs so the user can update the mtimer after waking up from the non-retentive suspend. Reviewed-by: Cyan Yang Reviewed-by: Anup Patel Signed-off-by: Nick Hu Link: https://lore.kernel.org/r/20251020-cache-upstream-v7-10-69a132447d8a@sifive.com Signed-off-by: Anup Patel --- include/sbi_utils/timer/aclint_mtimer.h | 5 ++++ lib/utils/timer/aclint_mtimer.c | 38 +++++++++++++++++-------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/include/sbi_utils/timer/aclint_mtimer.h b/include/sbi_utils/timer/aclint_mtimer.h index a245e13e..f8d2e5b4 100644 --- a/include/sbi_utils/timer/aclint_mtimer.h +++ b/include/sbi_utils/timer/aclint_mtimer.h @@ -42,6 +42,11 @@ struct aclint_mtimer_data { void (*time_wr)(bool timecmp, u64 value, volatile u64 *addr); }; +struct aclint_mtimer_data *aclint_get_mtimer_data(void); + +void aclint_mtimer_update(struct aclint_mtimer_data *mt, + struct aclint_mtimer_data *ref); + void aclint_mtimer_sync(struct aclint_mtimer_data *mt); void aclint_mtimer_set_reference(struct aclint_mtimer_data *mt, diff --git a/lib/utils/timer/aclint_mtimer.c b/lib/utils/timer/aclint_mtimer.c index 3db3c3be..fd6189aa 100644 --- a/lib/utils/timer/aclint_mtimer.c +++ b/lib/utils/timer/aclint_mtimer.c @@ -109,10 +109,34 @@ static struct sbi_timer_device mtimer = { .timer_event_stop = mtimer_event_stop }; -void aclint_mtimer_sync(struct aclint_mtimer_data *mt) +struct aclint_mtimer_data *aclint_get_mtimer_data(void) +{ + return mtimer_get_hart_data_ptr(sbi_scratch_thishart_ptr()); +} + +void aclint_mtimer_update(struct aclint_mtimer_data *mt, + struct aclint_mtimer_data *ref) { u64 v1, v2, mv, delta; u64 *mt_time_val, *ref_time_val; + + if (!mt || !ref || !mt->time_rd || !mt->time_wr || !ref->time_rd) + return; + + mt_time_val = (void *)mt->mtime_addr; + ref_time_val = (void *)ref->mtime_addr; + if (!atomic_raw_xchg_ulong(&mt->time_delta_computed, 1)) { + v1 = mt->time_rd(mt_time_val); + mv = ref->time_rd(ref_time_val); + v2 = mt->time_rd(mt_time_val); + delta = mv - ((v1 / 2) + (v2 / 2)); + mt->time_wr(false, mt->time_rd(mt_time_val) + delta, + mt_time_val); + } +} + +void aclint_mtimer_sync(struct aclint_mtimer_data *mt) +{ struct aclint_mtimer_data *reference; /* Sync-up non-shared MTIME if reference is available */ @@ -120,17 +144,7 @@ void aclint_mtimer_sync(struct aclint_mtimer_data *mt) return; reference = mt->time_delta_reference; - mt_time_val = (void *)mt->mtime_addr; - ref_time_val = (void *)reference->mtime_addr; - if (!atomic_raw_xchg_ulong(&mt->time_delta_computed, 1)) { - v1 = mt->time_rd(mt_time_val); - mv = reference->time_rd(ref_time_val); - v2 = mt->time_rd(mt_time_val); - delta = mv - ((v1 / 2) + (v2 / 2)); - mt->time_wr(false, mt->time_rd(mt_time_val) + delta, - mt_time_val); - } - + aclint_mtimer_update(mt, reference); } void aclint_mtimer_set_reference(struct aclint_mtimer_data *mt,