Skip to content

Commit a38b71b

Browse files
Marc Zyngierdlezcano
Marc Zyngier
authored andcommitted
clocksource/drivers/arm_arch_timer: Move system register timer programming over to CVAL
In order to cope better with high frequency counters, move the programming of the timers from the countdown timer (TVAL) over to the comparator (CVAL). The programming model is slightly different, as we now need to read the current counter value to have an absolute deadline instead of a relative one. There is a small overhead to this change, which we will address in the following patches. Reviewed-by: Oliver Upton <oupton@google.com> Reviewed-by: Mark Rutland <mark.rutland@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20211017124225.3018098-5-maz@kernel.org Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
1 parent 1e8d929 commit a38b71b

File tree

4 files changed

+33
-12
lines changed

4 files changed

+33
-12
lines changed

arch/arm/include/asm/arch_timer.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
3131
case ARCH_TIMER_REG_CTRL:
3232
asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
3333
break;
34-
case ARCH_TIMER_REG_TVAL:
35-
asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val));
34+
case ARCH_TIMER_REG_CVAL:
35+
asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
3636
break;
3737
default:
3838
BUILD_BUG();
@@ -42,8 +42,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
4242
case ARCH_TIMER_REG_CTRL:
4343
asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
4444
break;
45-
case ARCH_TIMER_REG_TVAL:
46-
asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val));
45+
case ARCH_TIMER_REG_CVAL:
46+
asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
4747
break;
4848
default:
4949
BUILD_BUG();

arch/arm64/include/asm/arch_timer.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
9696
case ARCH_TIMER_REG_CTRL:
9797
write_sysreg(val, cntp_ctl_el0);
9898
break;
99-
case ARCH_TIMER_REG_TVAL:
100-
write_sysreg(val, cntp_tval_el0);
99+
case ARCH_TIMER_REG_CVAL:
100+
write_sysreg(val, cntp_cval_el0);
101101
break;
102102
default:
103103
BUILD_BUG();
@@ -107,8 +107,8 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
107107
case ARCH_TIMER_REG_CTRL:
108108
write_sysreg(val, cntv_ctl_el0);
109109
break;
110-
case ARCH_TIMER_REG_TVAL:
111-
write_sysreg(val, cntv_tval_el0);
110+
case ARCH_TIMER_REG_CVAL:
111+
write_sysreg(val, cntv_cval_el0);
112112
break;
113113
default:
114114
BUILD_BUG();
@@ -121,7 +121,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
121121
}
122122

123123
static __always_inline
124-
u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
124+
u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
125125
{
126126
if (access == ARCH_TIMER_PHYS_ACCESS) {
127127
switch (reg) {

drivers/clocksource/arm_arch_timer.c

+23-3
Original file line numberDiff line numberDiff line change
@@ -691,10 +691,18 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
691691
struct clock_event_device *clk)
692692
{
693693
unsigned long ctrl;
694+
u64 cnt;
695+
694696
ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
695697
ctrl |= ARCH_TIMER_CTRL_ENABLE;
696698
ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
697-
arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
699+
700+
if (access == ARCH_TIMER_PHYS_ACCESS)
701+
cnt = __arch_counter_get_cntpct();
702+
else
703+
cnt = __arch_counter_get_cntvct();
704+
705+
arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk);
698706
arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
699707
}
700708

@@ -712,17 +720,29 @@ static int arch_timer_set_next_event_phys(unsigned long evt,
712720
return 0;
713721
}
714722

723+
static __always_inline void set_next_event_mem(const int access, unsigned long evt,
724+
struct clock_event_device *clk)
725+
{
726+
unsigned long ctrl;
727+
ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
728+
ctrl |= ARCH_TIMER_CTRL_ENABLE;
729+
ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
730+
731+
arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
732+
arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
733+
}
734+
715735
static int arch_timer_set_next_event_virt_mem(unsigned long evt,
716736
struct clock_event_device *clk)
717737
{
718-
set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
738+
set_next_event_mem(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
719739
return 0;
720740
}
721741

722742
static int arch_timer_set_next_event_phys_mem(unsigned long evt,
723743
struct clock_event_device *clk)
724744
{
725-
set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
745+
set_next_event_mem(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
726746
return 0;
727747
}
728748

include/clocksource/arm_arch_timer.h

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
enum arch_timer_reg {
2626
ARCH_TIMER_REG_CTRL,
2727
ARCH_TIMER_REG_TVAL,
28+
ARCH_TIMER_REG_CVAL,
2829
};
2930

3031
enum arch_timer_ppi_nr {

0 commit comments

Comments
 (0)