Commit 6b34df9e authored by Olof Johansson's avatar Olof Johansson

Merge branch 'clocksource/physical-timers' into next/drivers

* clocksource/physical-timers:
  clocksource: arch_timer: Allow the device tree to specify uninitialized timer registers
  clocksource: arch_timer: Fix code to use physical timers when requested
parents e58e501a 65b5732d
...@@ -22,6 +22,14 @@ to deliver its interrupts via SPIs. ...@@ -22,6 +22,14 @@ to deliver its interrupts via SPIs.
- always-on : a boolean property. If present, the timer is powered through an - always-on : a boolean property. If present, the timer is powered through an
always-on power domain, therefore it never loses context. always-on power domain, therefore it never loses context.
** Optional properties:
- arm,cpu-registers-not-fw-configured : Firmware does not initialize
any of the generic timer CPU registers, which contain their
architecturally-defined reset values. Only supported for 32-bit
systems which follow the ARMv7 architected reset values.
Example: Example:
timer { timer {
......
...@@ -78,6 +78,15 @@ static inline u32 arch_timer_get_cntfrq(void) ...@@ -78,6 +78,15 @@ static inline u32 arch_timer_get_cntfrq(void)
return val; return val;
} }
static inline u64 arch_counter_get_cntpct(void)
{
u64 cval;
isb();
asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
return cval;
}
static inline u64 arch_counter_get_cntvct(void) static inline u64 arch_counter_get_cntvct(void)
{ {
u64 cval; u64 cval;
......
...@@ -104,6 +104,15 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl) ...@@ -104,6 +104,15 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl)); asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
} }
static inline u64 arch_counter_get_cntpct(void)
{
/*
* AArch64 kernel and user space mandate the use of CNTVCT.
*/
BUG();
return 0;
}
static inline u64 arch_counter_get_cntvct(void) static inline u64 arch_counter_get_cntvct(void)
{ {
u64 cval; u64 cval;
......
...@@ -462,7 +462,10 @@ static void __init arch_counter_register(unsigned type) ...@@ -462,7 +462,10 @@ static void __init arch_counter_register(unsigned type)
/* Register the CP15 based counter if we have one */ /* Register the CP15 based counter if we have one */
if (type & ARCH_CP15_TIMER) { if (type & ARCH_CP15_TIMER) {
arch_timer_read_counter = arch_counter_get_cntvct; if (arch_timer_use_virtual)
arch_timer_read_counter = arch_counter_get_cntvct;
else
arch_timer_read_counter = arch_counter_get_cntpct;
} else { } else {
arch_timer_read_counter = arch_counter_get_cntvct_mem; arch_timer_read_counter = arch_counter_get_cntvct_mem;
...@@ -701,6 +704,14 @@ static void __init arch_timer_init(struct device_node *np) ...@@ -701,6 +704,14 @@ static void __init arch_timer_init(struct device_node *np)
arch_timer_ppi[i] = irq_of_parse_and_map(np, i); arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
arch_timer_detect_rate(NULL, np); arch_timer_detect_rate(NULL, np);
/*
* If we cannot rely on firmware initializing the timer registers then
* we should use the physical timers instead.
*/
if (IS_ENABLED(CONFIG_ARM) &&
of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
arch_timer_use_virtual = false;
/* /*
* If HYP mode is available, we know that the physical timer * If HYP mode is available, we know that the physical timer
* has been configured to be accessible from PL1. Use it, so * has been configured to be accessible from PL1. Use it, so
......
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