In devices where the U-Boot is used as a secondary bootloader, we rely
on the device's primary bootloader to implement CNTFRQ_EL0. However,
this reliance may lead to a non-functional timer in broken firmware.
For instance, some versions of Samsung's S-Boot don't implement it. It's
also not possible to set it in the U-Boot, because it's booted in a lower
exception level. CNTFRQ_EL0 is reported to be 0.
Use gd->arch.timer_rate_hz to override the queried value if set. This
setting needs to be done in the board file, preferrably in timer_init().
This feature is present only when the CONFIG_ARMV8_CNTFRQ_BROKEN is
enabled.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
bool "Force cache maintenance to be exclusively by VA"
depends on !SYS_DISABLE_DCACHE_OPS
+config ARMV8_CNTFRQ_BROKEN
+ bool "Fix broken ARMv8 generic timer"
+ depends on SYS_ARCH_TIMER
+ help
+ Say Y here if U-Boot depends on a prior stage bootloader, which
+ does not set the CNTFRQ_EL0 frequency, and its not possible to
+ set it from U-Boot either.
+
config ARMV8_SPL_EXCEPTION_VECTORS
bool "Install crash dump exception vectors"
depends on SPL
unsigned long notrace get_tbclk(void)
{
unsigned long cntfrq;
+
+ if (IS_ENABLED(CONFIG_ARMV8_CNTFRQ_BROKEN) && gd->arch.timer_rate_hz)
+ return gd->arch.timer_rate_hz;
+
asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq));
return cntfrq;
}