summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonghwa Lee <jonghwa3.lee@samsung.com>2015-08-07 16:42:26 +0900
committerSeung-Woo Kim <sw0312.kim@samsung.com>2016-12-14 13:47:04 +0900
commit0f2f3c13e883d7c1aaeea46f29112b43243cfc7b (patch)
treedf6a50314736aacf3e8d2d8fc3bf112144542740
parentd79533c104c68d59075b5cdd1cbe58512d5b8cfc (diff)
LOCAL \ clocksource: arch_timer: Use physical cnt instead of virtual one.
This fixes unsynchronized timestamp on kernel log which is occured by unitialized virtual counter of each CPU. Even ARM commented that to use virtual counter is mandatory on ARMv8, but it failed on EXYNOS5433. Let it uses physical counter instead of virtual counter on EXYNOS5433. Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
-rw-r--r--arch/arm64/include/asm/arch_timer.h15
-rw-r--r--drivers/clocksource/arm_arch_timer.c11
2 files changed, 25 insertions, 1 deletions
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index fbe0ca31a99c..effff73d6b4f 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -105,6 +105,11 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
}
+/* FIXME :
+ * For the case which firmware doesn't initialize virtual counter,
+ * it recalls the way of reading physical counter.
+ */
+#if 0
static inline u64 arch_counter_get_cntpct(void)
{
/*
@@ -113,6 +118,16 @@ static inline u64 arch_counter_get_cntpct(void)
BUG();
return 0;
}
+#endif
+static inline u64 arch_counter_get_cntpct(void)
+{
+ u64 cval;
+
+ isb();
+ asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
+
+ return cval;
+}
static inline u64 arch_counter_get_cntvct(void)
{
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 0aa135ddbf80..7c67e63cfe49 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -468,7 +468,7 @@ static void __init arch_counter_register(unsigned type)
/* Register the CP15 based counter if we have one */
if (type & ARCH_CP15_TIMER) {
- if (IS_ENABLED(CONFIG_ARM64) || arch_timer_use_virtual)
+ if (arch_timer_use_virtual)
arch_timer_read_counter = arch_counter_get_cntvct;
else
arch_timer_read_counter = arch_counter_get_cntpct;
@@ -737,6 +737,15 @@ static void __init arch_timer_of_init(struct device_node *np)
arch_timer_c3stop = !of_property_read_bool(np, "always-on");
+ /* FIXME :
+ * ARM recommended to use vcnt for clocksource of ARMv8.
+ * However, On Exynos5433, it seemed that they aren't intialized
+ * properly, each of counters' value are not synchronized.
+ * For Exynos5433, let it uses pcnt for representive clock source.
+ */
+ if (of_machine_is_compatible("samsung,exynos5433"))
+ arch_timer_use_virtual = false;
+
/*
* If we cannot rely on firmware initializing the timer registers then
* we should use the physical timers instead.