You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
4.3 KiB
118 lines
4.3 KiB
From f2e600c149fda3453344f89c7e9353fe278ebd32 Mon Sep 17 00:00:00 2001
|
|
From: Christoffer Dall <christoffer.dall@linaro.org>
|
|
Date: Wed, 18 Oct 2017 13:06:25 +0200
|
|
Subject: [PATCH] arm64: Implement arch_counter_get_cntpct to read the physical
|
|
counter
|
|
|
|
As we are about to use the physical counter on arm64 systems that have
|
|
KVM support, implement arch_counter_get_cntpct() and the associated
|
|
errata workaround functionality for stable timer reads.
|
|
|
|
Cc: Will Deacon <will.deacon@arm.com>
|
|
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
|
|
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
|
|
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
|
|
---
|
|
arch/arm64/include/asm/arch_timer.h | 8 +++-----
|
|
drivers/clocksource/arm_arch_timer.c | 23 +++++++++++++++++++++++
|
|
2 files changed, 26 insertions(+), 5 deletions(-)
|
|
|
|
--- a/arch/arm64/include/asm/arch_timer.h
|
|
+++ b/arch/arm64/include/asm/arch_timer.h
|
|
@@ -52,6 +52,7 @@ struct arch_timer_erratum_workaround {
|
|
const char *desc;
|
|
u32 (*read_cntp_tval_el0)(void);
|
|
u32 (*read_cntv_tval_el0)(void);
|
|
+ u64 (*read_cntpct_el0)(void);
|
|
u64 (*read_cntvct_el0)(void);
|
|
int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
|
|
int (*set_next_event_virt)(unsigned long, struct clock_event_device *);
|
|
@@ -148,11 +149,8 @@ static inline void arch_timer_set_cntkct
|
|
|
|
static inline u64 arch_counter_get_cntpct(void)
|
|
{
|
|
- /*
|
|
- * AArch64 kernel and user space mandate the use of CNTVCT.
|
|
- */
|
|
- BUG();
|
|
- return 0;
|
|
+ isb();
|
|
+ return arch_timer_reg_read_stable(cntpct_el0);
|
|
}
|
|
|
|
static inline u64 arch_counter_get_cntvct(void)
|
|
--- a/drivers/clocksource/arm_arch_timer.c
|
|
+++ b/drivers/clocksource/arm_arch_timer.c
|
|
@@ -217,6 +217,11 @@ static u32 notrace fsl_a008585_read_cntv
|
|
return __fsl_a008585_read_reg(cntv_tval_el0);
|
|
}
|
|
|
|
+static u64 notrace fsl_a008585_read_cntpct_el0(void)
|
|
+{
|
|
+ return __fsl_a008585_read_reg(cntpct_el0);
|
|
+}
|
|
+
|
|
static u64 notrace fsl_a008585_read_cntvct_el0(void)
|
|
{
|
|
return __fsl_a008585_read_reg(cntvct_el0);
|
|
@@ -258,6 +263,11 @@ static u32 notrace hisi_161010101_read_c
|
|
return __hisi_161010101_read_reg(cntv_tval_el0);
|
|
}
|
|
|
|
+static u64 notrace hisi_161010101_read_cntpct_el0(void)
|
|
+{
|
|
+ return __hisi_161010101_read_reg(cntpct_el0);
|
|
+}
|
|
+
|
|
static u64 notrace hisi_161010101_read_cntvct_el0(void)
|
|
{
|
|
return __hisi_161010101_read_reg(cntvct_el0);
|
|
@@ -288,6 +298,15 @@ static struct ate_acpi_oem_info hisi_161
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARM64_ERRATUM_858921
|
|
+static u64 notrace arm64_858921_read_cntpct_el0(void)
|
|
+{
|
|
+ u64 old, new;
|
|
+
|
|
+ old = read_sysreg(cntpct_el0);
|
|
+ new = read_sysreg(cntpct_el0);
|
|
+ return (((old ^ new) >> 32) & 1) ? old : new;
|
|
+}
|
|
+
|
|
static u64 notrace arm64_858921_read_cntvct_el0(void)
|
|
{
|
|
u64 old, new;
|
|
@@ -346,6 +365,7 @@ static const struct arch_timer_erratum_w
|
|
.desc = "Freescale erratum a005858",
|
|
.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
|
|
.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
|
|
+ .read_cntpct_el0 = fsl_a008585_read_cntpct_el0,
|
|
.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
|
|
.set_next_event_phys = erratum_set_next_event_tval_phys,
|
|
.set_next_event_virt = erratum_set_next_event_tval_virt,
|
|
@@ -358,6 +378,7 @@ static const struct arch_timer_erratum_w
|
|
.desc = "HiSilicon erratum 161010101",
|
|
.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
|
|
.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
|
|
+ .read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
|
|
.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
|
|
.set_next_event_phys = erratum_set_next_event_tval_phys,
|
|
.set_next_event_virt = erratum_set_next_event_tval_virt,
|
|
@@ -368,6 +389,7 @@ static const struct arch_timer_erratum_w
|
|
.desc = "HiSilicon erratum 161010101",
|
|
.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
|
|
.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
|
|
+ .read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
|
|
.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
|
|
.set_next_event_phys = erratum_set_next_event_tval_phys,
|
|
.set_next_event_virt = erratum_set_next_event_tval_virt,
|
|
@@ -378,6 +400,7 @@ static const struct arch_timer_erratum_w
|
|
.match_type = ate_match_local_cap_id,
|
|
.id = (void *)ARM64_WORKAROUND_858921,
|
|
.desc = "ARM erratum 858921",
|
|
+ .read_cntpct_el0 = arm64_858921_read_cntpct_el0,
|
|
.read_cntvct_el0 = arm64_858921_read_cntvct_el0,
|
|
},
|
|
#endif
|
|
|