-/* $OpenBSD: usertc.c,v 1.2 2020/07/15 22:58:33 kettenis Exp $ */
+/* $OpenBSD: usertc.c,v 1.3 2023/02/05 13:37:51 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
*
#include <sys/types.h>
#include <sys/timetc.h>
+static inline uint64_t
+agtimer_readcnt64_sun50i(void)
+{
+ uint64_t val;
+ int retry;
+
+ __asm volatile("isb" ::: "memory");
+ for (retry = 0; retry < 150; retry++) {
+ __asm volatile("mrs %x0, CNTVCT_EL0" : "=r" (val));
+
+ if (((val + 1) & 0x1ff) > 1)
+ break;
+ }
+
+ return val;
+}
+
static inline u_int
-agtimer_get_timecount(struct timecounter *tc)
+agtimer_get_timecount_default(struct timecounter *tc)
{
uint64_t val;
return (val & 0xffffffff);
}
+static inline u_int
+agtimer_get_timecount_sun50i(struct timecounter *tc)
+{
+ return agtimer_readcnt64_sun50i();
+}
+
static int
tc_get_timecount(struct timekeep *tk, u_int *tc)
{
switch (tk->tk_user) {
case TC_AGTIMER:
- *tc = agtimer_get_timecount(NULL);
+ *tc = agtimer_get_timecount_default(NULL);
+ return 0;
+ case TC_AGTIMER_SUN50I:
+ *tc = agtimer_get_timecount_sun50i(NULL);
return 0;
}