diff options
author | Andre Przywara <andre.przywara@arm.com> | 2018-06-27 01:42:52 +0100 |
---|---|---|
committer | Jagan Teki <jagan@amarulasolutions.com> | 2018-07-03 21:59:46 +0530 |
commit | 38651588d3d9a977ca457049d6357408ddad4a8b (patch) | |
tree | 7db5ddddfb993a285052604c8058c229a59a4097 /arch | |
parent | 76d69eb01dee492f5ecf43c43d7301fec6c5b99f (diff) |
arm: timer: factor out FSL arch timer erratum workaround
At the moment we have the workaround for the Freescale arch timer
erratum A-008585 merged into the generic timer_read_counter() routine.
Split those two up, so that we can add other errata workaround more
easily. Also add an explaining comment on the way.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Tested-by: Jagan Teki <jagan@amarulasolutions.com>
Tested-by: Andreas Färber <afaerber@suse.de>
Tested-by: Guillaume Gardet <guillaume.gardet@free.fr>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/cpu/armv8/generic_timer.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c index bf07a706a0..3d04fde650 100644 --- a/arch/arm/cpu/armv8/generic_timer.c +++ b/arch/arm/cpu/armv8/generic_timer.c @@ -20,27 +20,46 @@ unsigned long get_tbclk(void) return cntfrq; } +#ifdef CONFIG_SYS_FSL_ERRATUM_A008585 /* - * Generic timer implementation of timer_read_counter() + * FSL erratum A-008585 says that the ARM generic timer counter "has the + * potential to contain an erroneous value for a small number of core + * clock cycles every time the timer value changes". + * This sometimes leads to a consecutive counter read returning a lower + * value than the previous one, thus reporting the time to go backwards. + * The workaround is to read the counter twice and only return when the value + * was the same in both reads. + * Assumes that the CPU runs in much higher frequency than the timer. */ unsigned long timer_read_counter(void) { unsigned long cntpct; -#ifdef CONFIG_SYS_FSL_ERRATUM_A008585 - /* This erratum number needs to be confirmed to match ARM document */ unsigned long temp; -#endif + isb(); asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); -#ifdef CONFIG_SYS_FSL_ERRATUM_A008585 asm volatile("mrs %0, cntpct_el0" : "=r" (temp)); while (temp != cntpct) { asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); asm volatile("mrs %0, cntpct_el0" : "=r" (temp)); } -#endif + return cntpct; } +#else +/* + * timer_read_counter() using the Arm Generic Timer (aka arch timer). + */ +unsigned long timer_read_counter(void) +{ + unsigned long cntpct; + + isb(); + asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); + + return cntpct; +} +#endif uint64_t get_ticks(void) { |