lib: sbi_timer: Introduce sbi_timer_compute_delta() and friends

The users of timer event have to compute next_event (aka timer value
in the future) based on desired units and unit frequency. Introduce
sbi_timer_compute_delta() and friends to simplify computing next_event
for timer event users.

Signed-off-by: Anup Patel <anup.patel@oss.qualcomm.com>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Link: https://lore.kernel.org/r/20260425104048.2335262-5-anup.patel@oss.qualcomm.com
Signed-off-by: Anup Patel <anup@brainfault.org>
diff --git a/include/sbi/sbi_timer.h b/include/sbi/sbi_timer.h
index 914a5f1..2a04092 100644
--- a/include/sbi/sbi_timer.h
+++ b/include/sbi/sbi_timer.h
@@ -88,6 +88,21 @@
 
 struct sbi_scratch;
 
+/** Compute timer value delta based on arbitary units */
+u64 sbi_timer_compute_delta(ulong units, u64 unit_freq);
+
+/** Compute timer value delta from milliseconds */
+static inline u64 sbi_timer_compute_mdelta(ulong msecs)
+{
+	return sbi_timer_compute_delta(msecs, 1000);
+}
+
+/** Compute timer value delta from microseconds */
+static inline u64 sbi_timer_compute_udelta(ulong usecs)
+{
+	return sbi_timer_compute_delta(usecs, 1000000);
+}
+
 /** Generic delay loop of desired granularity */
 void sbi_timer_delay_loop(ulong units, u64 unit_freq,
 			  void (*delay_fn)(void *), void *opaque);
@@ -125,6 +140,18 @@
 /** Get timer value for current HART */
 u64 sbi_timer_value(void);
 
+/** Compute timer value after specified milliseconds */
+static inline u64 sbi_timer_value_after_msecs(ulong msecs)
+{
+	return sbi_timer_value() + sbi_timer_compute_mdelta(msecs);
+}
+
+/** Compute timer value after specified microseconds */
+static inline u64 sbi_timer_value_after_usecs(ulong usecs)
+{
+	return sbi_timer_value() + sbi_timer_compute_udelta(usecs);
+}
+
 /** Get virtualized timer value for current HART */
 u64 sbi_timer_virt_value(void);
 
diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c
index 70b8b5d..4d737d2 100644
--- a/lib/sbi/sbi_timer.c
+++ b/lib/sbi/sbi_timer.c
@@ -58,6 +58,15 @@
 	cpu_relax();
 }
 
+u64 sbi_timer_compute_delta(ulong units, u64 unit_freq)
+{
+	u64 delta;
+
+	delta = ((u64)timer_dev->timer_freq * (u64)units);
+	delta = delta / unit_freq;
+	return delta;
+}
+
 void sbi_timer_delay_loop(ulong units, u64 unit_freq,
 			  void (*delay_fn)(void *), void *opaque)
 {
@@ -72,15 +81,12 @@
 	/* Save starting timer value */
 	start_val = get_time_val();
 
-	/* Compute desired timer value delta */
-	delta = ((u64)timer_dev->timer_freq * (u64)units);
-	delta = delta / unit_freq;
-
 	/* Use NOP delay function if delay function not available */
 	if (!delay_fn)
 		delay_fn = nop_delay_fn;
 
 	/* Busy loop until desired timer value delta reached */
+	delta = sbi_timer_compute_delta(units, unit_freq);
 	while ((get_time_val() - start_val) < delta)
 		delay_fn(opaque);
 }