summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2021-09-15 07:41:24 +0300
committerAnup Patel <anup@brainfault.org>2021-09-26 17:22:15 +0300
commit9d0ab35ab4e2b9edf022237e2592d999dfe54704 (patch)
tree1a13f3b9bf115657923f82ae9fb991d4b2f6f995 /lib
parent6355155f51d4b636a228b75d82ebbdc706174ae7 (diff)
downloadopensbi-9d0ab35ab4e2b9edf022237e2592d999dfe54704.tar.xz
lib: sbi: Add generic timer delay loop function
We now have frequency of the timer device provided by the platform support so we can emulate desired delay using a loop where the number loop iterations are based on timer frequency. This patch provides sbi_timer_delay_loop() for above purpose. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Xiang W <wxjstz@126.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/sbi/sbi_timer.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c
index 2759501..acdba92 100644
--- a/lib/sbi/sbi_timer.c
+++ b/lib/sbi/sbi_timer.c
@@ -8,7 +8,9 @@
*/
#include <sbi/riscv_asm.h>
+#include <sbi/riscv_barrier.h>
#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_console.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_hart.h>
#include <sbi/sbi_platform.h>
@@ -47,6 +49,38 @@ static u64 get_platform_ticks(void)
return timer_dev->timer_value();
}
+static void nop_delay_fn(void *opaque)
+{
+ cpu_relax();
+}
+
+void sbi_timer_delay_loop(ulong units, u64 unit_freq,
+ void (*delay_fn)(void *), void *opaque)
+{
+ u64 start_val, delta;
+
+ /* Do nothing if we don't have timer device */
+ if (!timer_dev || !get_time_val) {
+ sbi_printf("%s: called without timer device\n", __func__);
+ return;
+ }
+
+ /* 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 */
+ while ((get_time_val() - start_val) < delta)
+ delay_fn(opaque);
+}
+
u64 sbi_timer_value(void)
{
if (get_time_val)