Skip to content

Commit 8c4b810

Browse files
Marc Zyngierdlezcano
authored andcommitted
clocksource/drivers/arm_arch_timer: Use event stream scaling when available
With FEAT_ECV and the 1GHz counter, it is pretty likely that the event stream divider doesn't fit in the field that holds the divider value (we only have 4 bits to describe counter bits [15:0] Thankfully, FEAT_ECV also provides a scaling mechanism to switch the field to cover counter bits [23:8] instead. Enable this on arm64 when ECV is available (32bit doesn't have any detection infrastructure and is unlikely to be run on an ARMv8.6 system anyway). Signed-off-by: Marc Zyngier <maz@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Acked-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/r/20220203170502.2694422-1-maz@kernel.org Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
1 parent 0a3a4b9 commit 8c4b810

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

drivers/clocksource/arm_arch_timer.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,10 +880,19 @@ static void __arch_timer_setup(unsigned type,
880880
clockevents_config_and_register(clk, arch_timer_rate, 0xf, max_delta);
881881
}
882882

883-
static void arch_timer_evtstrm_enable(int divider)
883+
static void arch_timer_evtstrm_enable(unsigned int divider)
884884
{
885885
u32 cntkctl = arch_timer_get_cntkctl();
886886

887+
#ifdef CONFIG_ARM64
888+
/* ECV is likely to require a large divider. Use the EVNTIS flag. */
889+
if (cpus_have_const_cap(ARM64_HAS_ECV) && divider > 15) {
890+
cntkctl |= ARCH_TIMER_EVT_INTERVAL_SCALE;
891+
divider -= 8;
892+
}
893+
#endif
894+
895+
divider = min(divider, 15U);
887896
cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
888897
/* Set the divider and enable virtual event stream */
889898
cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
@@ -912,7 +921,7 @@ static void arch_timer_configure_evtstream(void)
912921
lsb++;
913922

914923
/* enable event stream */
915-
arch_timer_evtstrm_enable(max(0, min(lsb, 15)));
924+
arch_timer_evtstrm_enable(max(0, lsb));
916925
}
917926

918927
static void arch_counter_set_user_access(void)

include/clocksource/arm_arch_timer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum arch_timer_spi_nr {
5656
#define ARCH_TIMER_EVT_TRIGGER_MASK (0xF << ARCH_TIMER_EVT_TRIGGER_SHIFT)
5757
#define ARCH_TIMER_USR_VT_ACCESS_EN (1 << 8) /* virtual timer registers */
5858
#define ARCH_TIMER_USR_PT_ACCESS_EN (1 << 9) /* physical timer registers */
59+
#define ARCH_TIMER_EVT_INTERVAL_SCALE (1 << 17) /* EVNTIS in the ARMv8 ARM */
5960

6061
#define ARCH_TIMER_EVT_STREAM_PERIOD_US 100
6162
#define ARCH_TIMER_EVT_STREAM_FREQ \

0 commit comments

Comments
 (0)