Commit 57a315cd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'timers-core-2021-10-31' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer updates from Thomas Gleixner:
 "Time, timers and timekeeping updates:

   - No core updates

   - No new clocksource/event driver

   - A large rework of the ARM architected timer driver to prepare for
     the support of the upcoming ARMv8.6 support

   - Fix Kconfig options for Exynos MCT, Samsung PWM and TI DM timers

   - Address a namespace collison in the ARC sp804 timer driver"

* tag 'timers-core-2021-10-31' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  clocksource/drivers/timer-ti-dm: Select TIMER_OF
  clocksource/drivers/exynosy: Depend on sub-architecture for Exynos MCT and Samsung PWM
  clocksource/drivers/arch_arm_timer: Move workaround synchronisation around
  clocksource/drivers/arm_arch_timer: Fix masking for high freq counters
  clocksource/drivers/arm_arch_timer: Drop unnecessary ISB on CVAL programming
  clocksource/drivers/arm_arch_timer: Remove any trace of the TVAL programming interface
  clocksource/drivers/arm_arch_timer: Work around broken CVAL implementations
  clocksource/drivers/arm_arch_timer: Advertise 56bit timer to the core code
  clocksource/drivers/arm_arch_timer: Move MMIO timer programming over to CVAL
  clocksource/drivers/arm_arch_timer: Fix MMIO base address vs callback ordering issue
  clocksource/drivers/arm_arch_timer: Move drop _tval from erratum function names
  clocksource/drivers/arm_arch_timer: Move system register timer programming over to CVAL
  clocksource/drivers/arm_arch_timer: Extend write side of timer register accessors to u64
  clocksource/drivers/arm_arch_timer: Drop CNT*_TVAL read accessors
  clocksource/arm_arch_timer: Add build-time guards for unhandled register accesses
  clocksource/drivers/arc_timer: Eliminate redefined macro error
parents 43aa0a19 a8da61ce
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <asm/hwcap.h> #include <asm/hwcap.h>
#include <linux/clocksource.h> #include <linux/clocksource.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/types.h> #include <linux/types.h>
#include <clocksource/arm_arch_timer.h> #include <clocksource/arm_arch_timer.h>
...@@ -24,29 +25,35 @@ int arch_timer_arch_init(void); ...@@ -24,29 +25,35 @@ int arch_timer_arch_init(void);
* the code. At least it does so with a recent GCC (4.6.3). * the code. At least it does so with a recent GCC (4.6.3).
*/ */
static __always_inline static __always_inline
void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
{ {
if (access == ARCH_TIMER_PHYS_ACCESS) { if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) { switch (reg) {
case ARCH_TIMER_REG_CTRL: case ARCH_TIMER_REG_CTRL:
asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val)); asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
isb();
break; break;
case ARCH_TIMER_REG_TVAL: case ARCH_TIMER_REG_CVAL:
asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
break; break;
default:
BUILD_BUG();
} }
} else if (access == ARCH_TIMER_VIRT_ACCESS) { } else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) { switch (reg) {
case ARCH_TIMER_REG_CTRL: case ARCH_TIMER_REG_CTRL:
asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val)); asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
isb();
break; break;
case ARCH_TIMER_REG_TVAL: case ARCH_TIMER_REG_CVAL:
asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val)); asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
break; break;
default:
BUILD_BUG();
} }
} else {
BUILD_BUG();
} }
isb();
} }
static __always_inline static __always_inline
...@@ -59,19 +66,19 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) ...@@ -59,19 +66,19 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
case ARCH_TIMER_REG_CTRL: case ARCH_TIMER_REG_CTRL:
asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
break; break;
case ARCH_TIMER_REG_TVAL: default:
asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); BUILD_BUG();
break;
} }
} else if (access == ARCH_TIMER_VIRT_ACCESS) { } else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) { switch (reg) {
case ARCH_TIMER_REG_CTRL: case ARCH_TIMER_REG_CTRL:
asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val)); asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
break; break;
case ARCH_TIMER_REG_TVAL: default:
asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val)); BUILD_BUG();
break;
} }
} else {
BUILD_BUG();
} }
return val; return val;
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
({ \ ({ \
const struct arch_timer_erratum_workaround *__wa; \ const struct arch_timer_erratum_workaround *__wa; \
__wa = __this_cpu_read(timer_unstable_counter_workaround); \ __wa = __this_cpu_read(timer_unstable_counter_workaround); \
(__wa && __wa->h) ? __wa->h : arch_timer_##h; \ (__wa && __wa->h) ? ({ isb(); __wa->h;}) : arch_timer_##h; \
}) })
#else #else
...@@ -52,8 +52,6 @@ struct arch_timer_erratum_workaround { ...@@ -52,8 +52,6 @@ struct arch_timer_erratum_workaround {
enum arch_timer_erratum_match_type match_type; enum arch_timer_erratum_match_type match_type;
const void *id; const void *id;
const char *desc; const char *desc;
u32 (*read_cntp_tval_el0)(void);
u32 (*read_cntv_tval_el0)(void);
u64 (*read_cntpct_el0)(void); u64 (*read_cntpct_el0)(void);
u64 (*read_cntvct_el0)(void); u64 (*read_cntvct_el0)(void);
int (*set_next_event_phys)(unsigned long, struct clock_event_device *); int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
...@@ -64,24 +62,15 @@ struct arch_timer_erratum_workaround { ...@@ -64,24 +62,15 @@ struct arch_timer_erratum_workaround {
DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *, DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
timer_unstable_counter_workaround); timer_unstable_counter_workaround);
/* inline sysreg accessors that make erratum_handler() work */
static inline notrace u32 arch_timer_read_cntp_tval_el0(void)
{
return read_sysreg(cntp_tval_el0);
}
static inline notrace u32 arch_timer_read_cntv_tval_el0(void)
{
return read_sysreg(cntv_tval_el0);
}
static inline notrace u64 arch_timer_read_cntpct_el0(void) static inline notrace u64 arch_timer_read_cntpct_el0(void)
{ {
isb();
return read_sysreg(cntpct_el0); return read_sysreg(cntpct_el0);
} }
static inline notrace u64 arch_timer_read_cntvct_el0(void) static inline notrace u64 arch_timer_read_cntvct_el0(void)
{ {
isb();
return read_sysreg(cntvct_el0); return read_sysreg(cntvct_el0);
} }
...@@ -102,51 +91,58 @@ static inline notrace u64 arch_timer_read_cntvct_el0(void) ...@@ -102,51 +91,58 @@ static inline notrace u64 arch_timer_read_cntvct_el0(void)
* the code. * the code.
*/ */
static __always_inline static __always_inline
void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
{ {
if (access == ARCH_TIMER_PHYS_ACCESS) { if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) { switch (reg) {
case ARCH_TIMER_REG_CTRL: case ARCH_TIMER_REG_CTRL:
write_sysreg(val, cntp_ctl_el0); write_sysreg(val, cntp_ctl_el0);
isb();
break; break;
case ARCH_TIMER_REG_TVAL: case ARCH_TIMER_REG_CVAL:
write_sysreg(val, cntp_tval_el0); write_sysreg(val, cntp_cval_el0);
break; break;
default:
BUILD_BUG();
} }
} else if (access == ARCH_TIMER_VIRT_ACCESS) { } else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) { switch (reg) {
case ARCH_TIMER_REG_CTRL: case ARCH_TIMER_REG_CTRL:
write_sysreg(val, cntv_ctl_el0); write_sysreg(val, cntv_ctl_el0);
isb();
break; break;
case ARCH_TIMER_REG_TVAL: case ARCH_TIMER_REG_CVAL:
write_sysreg(val, cntv_tval_el0); write_sysreg(val, cntv_cval_el0);
break; break;
default:
BUILD_BUG();
} }
} else {
BUILD_BUG();
} }
isb();
} }
static __always_inline static __always_inline
u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
{ {
if (access == ARCH_TIMER_PHYS_ACCESS) { if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) { switch (reg) {
case ARCH_TIMER_REG_CTRL: case ARCH_TIMER_REG_CTRL:
return read_sysreg(cntp_ctl_el0); return read_sysreg(cntp_ctl_el0);
case ARCH_TIMER_REG_TVAL: default:
return arch_timer_reg_read_stable(cntp_tval_el0); BUILD_BUG();
} }
} else if (access == ARCH_TIMER_VIRT_ACCESS) { } else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) { switch (reg) {
case ARCH_TIMER_REG_CTRL: case ARCH_TIMER_REG_CTRL:
return read_sysreg(cntv_ctl_el0); return read_sysreg(cntv_ctl_el0);
case ARCH_TIMER_REG_TVAL: default:
return arch_timer_reg_read_stable(cntv_tval_el0); BUILD_BUG();
} }
} }
BUG(); BUILD_BUG();
unreachable();
} }
static inline u32 arch_timer_get_cntfrq(void) static inline u32 arch_timer_get_cntfrq(void)
...@@ -169,7 +165,6 @@ static __always_inline u64 __arch_counter_get_cntpct_stable(void) ...@@ -169,7 +165,6 @@ static __always_inline u64 __arch_counter_get_cntpct_stable(void)
{ {
u64 cnt; u64 cnt;
isb();
cnt = arch_timer_reg_read_stable(cntpct_el0); cnt = arch_timer_reg_read_stable(cntpct_el0);
arch_counter_enforce_ordering(cnt); arch_counter_enforce_ordering(cnt);
return cnt; return cnt;
...@@ -189,7 +184,6 @@ static __always_inline u64 __arch_counter_get_cntvct_stable(void) ...@@ -189,7 +184,6 @@ static __always_inline u64 __arch_counter_get_cntvct_stable(void)
{ {
u64 cnt; u64 cnt;
isb();
cnt = arch_timer_reg_read_stable(cntvct_el0); cnt = arch_timer_reg_read_stable(cntvct_el0);
arch_counter_enforce_ordering(cnt); arch_counter_enforce_ordering(cnt);
return cnt; return cnt;
......
...@@ -24,6 +24,7 @@ config I8253_LOCK ...@@ -24,6 +24,7 @@ config I8253_LOCK
config OMAP_DM_TIMER config OMAP_DM_TIMER
bool bool
select TIMER_OF
config CLKBLD_I8253 config CLKBLD_I8253
def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
...@@ -418,12 +419,14 @@ config ATMEL_TCB_CLKSRC ...@@ -418,12 +419,14 @@ config ATMEL_TCB_CLKSRC
config CLKSRC_EXYNOS_MCT config CLKSRC_EXYNOS_MCT
bool "Exynos multi core timer driver" if COMPILE_TEST bool "Exynos multi core timer driver" if COMPILE_TEST
depends on ARM || ARM64 depends on ARM || ARM64
depends on ARCH_EXYNOS || COMPILE_TEST
help help
Support for Multi Core Timer controller on Exynos SoCs. Support for Multi Core Timer controller on Exynos SoCs.
config CLKSRC_SAMSUNG_PWM config CLKSRC_SAMSUNG_PWM
bool "PWM timer driver for Samsung S3C, S5P" if COMPILE_TEST bool "PWM timer driver for Samsung S3C, S5P" if COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210 || COMPILE_TEST
help help
This is a new clocksource driver for the PWM timer found in This is a new clocksource driver for the PWM timer found in
Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
......
...@@ -225,7 +225,7 @@ static int __init arc_cs_setup_timer1(struct device_node *node) ...@@ -225,7 +225,7 @@ static int __init arc_cs_setup_timer1(struct device_node *node)
write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMERN_MAX); write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMERN_MAX);
write_aux_reg(ARC_REG_TIMER1_CNT, 0); write_aux_reg(ARC_REG_TIMER1_CNT, 0);
write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); write_aux_reg(ARC_REG_TIMER1_CTRL, ARC_TIMER_CTRL_NH);
sched_clock_register(arc_timer1_clock_read, 32, arc_timer_freq); sched_clock_register(arc_timer1_clock_read, 32, arc_timer_freq);
...@@ -245,7 +245,7 @@ static void arc_timer_event_setup(unsigned int cycles) ...@@ -245,7 +245,7 @@ static void arc_timer_event_setup(unsigned int cycles)
write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles); write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles);
write_aux_reg(ARC_REG_TIMER0_CNT, 0); /* start from 0 */ write_aux_reg(ARC_REG_TIMER0_CNT, 0); /* start from 0 */
write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH); write_aux_reg(ARC_REG_TIMER0_CTRL, ARC_TIMER_CTRL_IE | ARC_TIMER_CTRL_NH);
} }
...@@ -294,7 +294,7 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id) ...@@ -294,7 +294,7 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
* explicitly clears IP bit * explicitly clears IP bit
* 2. Re-arm interrupt if periodic by writing to IE bit [0] * 2. Re-arm interrupt if periodic by writing to IE bit [0]
*/ */
write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | TIMER_CTRL_NH); write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | ARC_TIMER_CTRL_NH);
evt->event_handler(evt); evt->event_handler(evt);
......
This diff is collapsed.
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
enum arch_timer_reg { enum arch_timer_reg {
ARCH_TIMER_REG_CTRL, ARCH_TIMER_REG_CTRL,
ARCH_TIMER_REG_TVAL, ARCH_TIMER_REG_CVAL,
}; };
enum arch_timer_ppi_nr { enum arch_timer_ppi_nr {
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */ #define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
/* CTRL reg bits */ /* CTRL reg bits */
#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */ #define ARC_TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */
#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ #define ARC_TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
#define ARC_TIMERN_MAX 0xFFFFFFFF #define ARC_TIMERN_MAX 0xFFFFFFFF
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment