diff options
Diffstat (limited to 'drivers/clocksource')
| -rw-r--r-- | drivers/clocksource/Kconfig | 9 | ||||
| -rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 33 |
2 files changed, 28 insertions, 14 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 50f512629afd..64b8158675b5 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -158,6 +158,15 @@ config ARM_ARCH_TIMER_EVTSTREAM This must be disabled for hardware validation purposes to detect any hardware anomalies of missing events. +config MSM_TIMER_LEAP + bool "ARCH TIMER counter rollover" + default n + depends on ARM_ARCH_TIMER && ARM64 + help + This option enables a check for least significant 32 bits of + counter rollover. On every counter read if least significant + 32 bits are set, reread counter. + config ARM_ARCH_TIMER_VCT_ACCESS bool "Support for ARM architected timer virtual counter access in userspace" default !ARM64 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 1c029b49f96d..6760f84faf06 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -25,6 +25,7 @@ #include <linux/acpi.h> #include <asm/arch_timer.h> +#include <asm/traps.h> #include <asm/virt.h> #include <clocksource/arm_arch_timer.h> @@ -83,20 +84,20 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val, struct arch_timer *timer = to_arch_timer(clk); switch (reg) { case ARCH_TIMER_REG_CTRL: - writel_relaxed(val, timer->base + CNTP_CTL); + writel_relaxed_no_log(val, timer->base + CNTP_CTL); break; case ARCH_TIMER_REG_TVAL: - writel_relaxed(val, timer->base + CNTP_TVAL); + writel_relaxed_no_log(val, timer->base + CNTP_TVAL); break; } } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) { struct arch_timer *timer = to_arch_timer(clk); switch (reg) { case ARCH_TIMER_REG_CTRL: - writel_relaxed(val, timer->base + CNTV_CTL); + writel_relaxed_no_log(val, timer->base + CNTV_CTL); break; case ARCH_TIMER_REG_TVAL: - writel_relaxed(val, timer->base + CNTV_TVAL); + writel_relaxed_no_log(val, timer->base + CNTV_TVAL); break; } } else { @@ -114,20 +115,20 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, struct arch_timer *timer = to_arch_timer(clk); switch (reg) { case ARCH_TIMER_REG_CTRL: - val = readl_relaxed(timer->base + CNTP_CTL); + val = readl_relaxed_no_log(timer->base + CNTP_CTL); break; case ARCH_TIMER_REG_TVAL: - val = readl_relaxed(timer->base + CNTP_TVAL); + val = readl_relaxed_no_log(timer->base + CNTP_TVAL); break; } } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) { struct arch_timer *timer = to_arch_timer(clk); switch (reg) { case ARCH_TIMER_REG_CTRL: - val = readl_relaxed(timer->base + CNTV_CTL); + val = readl_relaxed_no_log(timer->base + CNTV_CTL); break; case ARCH_TIMER_REG_TVAL: - val = readl_relaxed(timer->base + CNTV_TVAL); + val = readl_relaxed_no_log(timer->base + CNTV_TVAL); break; } } else { @@ -328,11 +329,12 @@ static void arch_counter_set_user_access(void) /* 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_VT_ACCESS_EN; + if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS)) cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; else @@ -374,7 +376,8 @@ arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np) if (!acpi_disabled || of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) { if (cntbase) - arch_timer_rate = readl_relaxed(cntbase + CNTFRQ); + arch_timer_rate = readl_relaxed_no_log(cntbase + + CNTFRQ); else arch_timer_rate = arch_timer_get_cntfrq(); } @@ -411,9 +414,9 @@ static u64 arch_counter_get_cntvct_mem(void) u32 vct_lo, vct_hi, tmp_hi; do { - vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); - vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO); - tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); + vct_hi = readl_relaxed_no_log(arch_counter_base + CNTVCT_HI); + vct_lo = readl_relaxed_no_log(arch_counter_base + CNTVCT_LO); + tmp_hi = readl_relaxed_no_log(arch_counter_base + CNTVCT_HI); } while (vct_hi != tmp_hi); return ((u64) vct_hi << 32) | vct_lo; @@ -689,6 +692,7 @@ static void __init arch_timer_common_init(void) arch_timer_banner(arch_timers_present); arch_counter_register(arch_timers_present); arch_timer_arch_init(); + clocksource_select_force(); } static void __init arch_timer_init(void) @@ -759,7 +763,7 @@ static void __init arch_timer_mem_init(struct device_node *np) return; } - cnttidr = readl_relaxed(cntctlbase + CNTTIDR); + cnttidr = readl_relaxed_no_log(cntctlbase + CNTTIDR); iounmap(cntctlbase); /* @@ -807,6 +811,7 @@ static void __init arch_timer_mem_init(struct device_node *np) arch_timer_detect_rate(base, np); arch_timer_mem_register(base, irq); arch_timer_common_init(); + get_pct_hook_init(); } CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", arch_timer_mem_init); |
