diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2019-02-23 19:21:53 +0300 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2019-02-23 19:21:53 +0300 |
commit | 8dd2eee2f444a7a570599bffc9da330157cca5b5 (patch) | |
tree | 400b9a2fb19e7ac5bac27750bdac77615eded541 /drivers/clocksource/arm_arch_timer.c | |
parent | 75b710af7139768fd4ba2d4e05335d2344796279 (diff) | |
parent | f40f4fc9506d6b2b786920059b320aac3a831574 (diff) | |
download | linux-8dd2eee2f444a7a570599bffc9da330157cca5b5.tar.xz |
Merge branch 'clockevents/5.1' of https://git.linaro.org/people/daniel.lezcano/linux into timers/core
Pull clockevents updates from Daniel Lezcano:
- Update the binding documentation for the gpt timer (Anson Huang)
- Improve checking and error handling at init time on risc timer (Atish
Patra)
- Update the binding documentation for r8a774c0 cmt and tmu (Biju Das)
- Fail gracefully when clock rate is unavailable on sun5i (Chen-Yu Tsai)
- Rename the tango-xtal, pxa and cs5535 to timer-*.c for consistency
(Daniel Lezcano)
- Add the support for the tegra210 timer and add the platform's Kconfig
selection (Joseph Lo)
- Do a cleanup in the header inclusions and remove the unused ones for the
exynos_mct timer driver (Krzysztof Kozlowski)
- Remove some non-of dead code and fix the error path when initializing
the resources in the exynos_mct timer driver (Marek Szyprowski)
- Update the DT bindings for the MT7629 (Ryder Lee)
- Provide a workaround for the arm arch timer for Allwinner A64 timers
(Samuel Holland)
- Clear the timer interrupt at shutdown time on the exynos_mct timer
driver (Stuart Menefy)
Diffstat (limited to 'drivers/clocksource/arm_arch_timer.c')
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 9a7d4dc00b6e..a8b20b65bd4b 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -326,6 +326,48 @@ static u64 notrace arm64_1188873_read_cntvct_el0(void) } #endif +#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1 +/* + * The low bits of the counter registers are indeterminate while bit 10 or + * greater is rolling over. Since the counter value can jump both backward + * (7ff -> 000 -> 800) and forward (7ff -> fff -> 800), ignore register values + * with all ones or all zeros in the low bits. Bound the loop by the maximum + * number of CPU cycles in 3 consecutive 24 MHz counter periods. + */ +#define __sun50i_a64_read_reg(reg) ({ \ + u64 _val; \ + int _retries = 150; \ + \ + do { \ + _val = read_sysreg(reg); \ + _retries--; \ + } while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries); \ + \ + WARN_ON_ONCE(!_retries); \ + _val; \ +}) + +static u64 notrace sun50i_a64_read_cntpct_el0(void) +{ + return __sun50i_a64_read_reg(cntpct_el0); +} + +static u64 notrace sun50i_a64_read_cntvct_el0(void) +{ + return __sun50i_a64_read_reg(cntvct_el0); +} + +static u32 notrace sun50i_a64_read_cntp_tval_el0(void) +{ + return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0(); +} + +static u32 notrace sun50i_a64_read_cntv_tval_el0(void) +{ + return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0(); +} +#endif + #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround); EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); @@ -423,6 +465,19 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .read_cntvct_el0 = arm64_1188873_read_cntvct_el0, }, #endif +#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1 + { + .match_type = ate_match_dt, + .id = "allwinner,erratum-unknown1", + .desc = "Allwinner erratum UNKNOWN1", + .read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0, + .read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0, + .read_cntpct_el0 = sun50i_a64_read_cntpct_el0, + .read_cntvct_el0 = sun50i_a64_read_cntvct_el0, + .set_next_event_phys = erratum_set_next_event_tval_phys, + .set_next_event_virt = erratum_set_next_event_tval_virt, + }, +#endif }; typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *, |