|
@@ -92,21 +92,47 @@ static inline u32 arch_timer_get_cntfrq(void)
|
|
|
return val;
|
|
|
}
|
|
|
|
|
|
-static inline void arch_counter_set_user_access(void)
|
|
|
+static inline u32 arch_timer_get_cntkctl(void)
|
|
|
{
|
|
|
u32 cntkctl;
|
|
|
-
|
|
|
asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl));
|
|
|
+ return cntkctl;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void arch_timer_set_cntkctl(u32 cntkctl)
|
|
|
+{
|
|
|
+ asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
|
|
|
+}
|
|
|
+
|
|
|
+static inline void arch_counter_set_user_access(void)
|
|
|
+{
|
|
|
+ u32 cntkctl = arch_timer_get_cntkctl();
|
|
|
|
|
|
/* Disable user access to the timers and the physical counter */
|
|
|
+ /* Also disable virtual event stream */
|
|
|
cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
|
|
|
| ARCH_TIMER_USR_VT_ACCESS_EN
|
|
|
+ | ARCH_TIMER_VIRT_EVT_EN
|
|
|
| ARCH_TIMER_USR_PCT_ACCESS_EN);
|
|
|
|
|
|
/* Enable user access to the virtual counter */
|
|
|
cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
|
|
|
|
|
|
- asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
|
|
|
+ arch_timer_set_cntkctl(cntkctl);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void arch_timer_evtstrm_enable(int divider)
|
|
|
+{
|
|
|
+ u32 cntkctl = arch_timer_get_cntkctl();
|
|
|
+ cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
|
|
|
+ /* Set the divider and enable virtual event stream */
|
|
|
+ cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
|
|
|
+ | ARCH_TIMER_VIRT_EVT_EN;
|
|
|
+ arch_timer_set_cntkctl(cntkctl);
|
|
|
+ elf_hwcap |= HWCAP_EVTSTRM;
|
|
|
+#ifdef CONFIG_COMPAT
|
|
|
+ compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
static inline u64 arch_counter_get_cntvct(void)
|