summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv8/generic_timer.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-07-01 13:17:56 -0600
committerTom Rini <trini@konsulko.com>2024-07-01 15:00:56 -0600
commit65fbdab27224ee3943a89496b21862db83c34da2 (patch)
tree775a0a54066c2e9a6bbba201676e3d896b5cb0e2 /arch/arm/cpu/armv8/generic_timer.c
parent3f772959501c99fbe5aa0b22a36efe3478d1ae1c (diff)
parentb4cbd1a257d4027038b4f997d73bdb0a066db045 (diff)
Merge branch 'next'
Diffstat (limited to 'arch/arm/cpu/armv8/generic_timer.c')
-rw-r--r--arch/arm/cpu/armv8/generic_timer.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c
index 8f83372cbca..1de7ec596fc 100644
--- a/arch/arm/cpu/armv8/generic_timer.c
+++ b/arch/arm/cpu/armv8/generic_timer.c
@@ -4,7 +4,6 @@
* David Feng <fenghua@phytium.com.cn>
*/
-#include <common.h>
#include <bootstage.h>
#include <command.h>
#include <time.h>
@@ -115,3 +114,30 @@ ulong timer_get_boot_us(void)
return val / get_tbclk();
}
+
+#if CONFIG_IS_ENABLED(ARMV8_UDELAY_EVENT_STREAM)
+void __udelay(unsigned long usec)
+{
+ u64 target = get_ticks() + usec_to_tick(usec);
+
+ /* At EL2 or above, use the event stream to avoid polling CNTPCT_EL0 so often */
+ if (current_el() >= 2) {
+ u32 cnthctl_val;
+ const u8 event_period = 0x7;
+
+ asm volatile("mrs %0, cnthctl_el2" : "=r" (cnthctl_val));
+ asm volatile("msr cnthctl_el2, %0" : : "r"
+ (cnthctl_val | CNTHCTL_EL2_EVNT_EN | CNTHCTL_EL2_EVNT_I(event_period)));
+
+ while (get_ticks() + (1ULL << event_period) <= target)
+ wfe();
+
+ /* Reset the event stream */
+ asm volatile("msr cnthctl_el2, %0" : : "r" (cnthctl_val));
+ }
+
+ /* Fall back to polling CNTPCT_EL0 */
+ while (get_ticks() <= target)
+ ;
+}
+#endif