diff options
Diffstat (limited to 'drivers/clocksource/arm_arch_timer.c')
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 538bfa8ba9b4..57cb2f00fc07 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -159,6 +159,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, | |||
159 | * if we don't have the cp15 accessors we won't have a problem. | 159 | * if we don't have the cp15 accessors we won't have a problem. |
160 | */ | 160 | */ |
161 | u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct; | 161 | u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct; |
162 | EXPORT_SYMBOL_GPL(arch_timer_read_counter); | ||
162 | 163 | ||
163 | static u64 arch_counter_read(struct clocksource *cs) | 164 | static u64 arch_counter_read(struct clocksource *cs) |
164 | { | 165 | { |
@@ -218,6 +219,11 @@ static u32 notrace fsl_a008585_read_cntv_tval_el0(void) | |||
218 | return __fsl_a008585_read_reg(cntv_tval_el0); | 219 | return __fsl_a008585_read_reg(cntv_tval_el0); |
219 | } | 220 | } |
220 | 221 | ||
222 | static u64 notrace fsl_a008585_read_cntpct_el0(void) | ||
223 | { | ||
224 | return __fsl_a008585_read_reg(cntpct_el0); | ||
225 | } | ||
226 | |||
221 | static u64 notrace fsl_a008585_read_cntvct_el0(void) | 227 | static u64 notrace fsl_a008585_read_cntvct_el0(void) |
222 | { | 228 | { |
223 | return __fsl_a008585_read_reg(cntvct_el0); | 229 | return __fsl_a008585_read_reg(cntvct_el0); |
@@ -259,6 +265,11 @@ static u32 notrace hisi_161010101_read_cntv_tval_el0(void) | |||
259 | return __hisi_161010101_read_reg(cntv_tval_el0); | 265 | return __hisi_161010101_read_reg(cntv_tval_el0); |
260 | } | 266 | } |
261 | 267 | ||
268 | static u64 notrace hisi_161010101_read_cntpct_el0(void) | ||
269 | { | ||
270 | return __hisi_161010101_read_reg(cntpct_el0); | ||
271 | } | ||
272 | |||
262 | static u64 notrace hisi_161010101_read_cntvct_el0(void) | 273 | static u64 notrace hisi_161010101_read_cntvct_el0(void) |
263 | { | 274 | { |
264 | return __hisi_161010101_read_reg(cntvct_el0); | 275 | return __hisi_161010101_read_reg(cntvct_el0); |
@@ -289,6 +300,15 @@ static struct ate_acpi_oem_info hisi_161010101_oem_info[] = { | |||
289 | #endif | 300 | #endif |
290 | 301 | ||
291 | #ifdef CONFIG_ARM64_ERRATUM_858921 | 302 | #ifdef CONFIG_ARM64_ERRATUM_858921 |
303 | static u64 notrace arm64_858921_read_cntpct_el0(void) | ||
304 | { | ||
305 | u64 old, new; | ||
306 | |||
307 | old = read_sysreg(cntpct_el0); | ||
308 | new = read_sysreg(cntpct_el0); | ||
309 | return (((old ^ new) >> 32) & 1) ? old : new; | ||
310 | } | ||
311 | |||
292 | static u64 notrace arm64_858921_read_cntvct_el0(void) | 312 | static u64 notrace arm64_858921_read_cntvct_el0(void) |
293 | { | 313 | { |
294 | u64 old, new; | 314 | u64 old, new; |
@@ -310,16 +330,19 @@ static void erratum_set_next_event_tval_generic(const int access, unsigned long | |||
310 | struct clock_event_device *clk) | 330 | struct clock_event_device *clk) |
311 | { | 331 | { |
312 | unsigned long ctrl; | 332 | unsigned long ctrl; |
313 | u64 cval = evt + arch_counter_get_cntvct(); | 333 | u64 cval; |
314 | 334 | ||
315 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); | 335 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); |
316 | ctrl |= ARCH_TIMER_CTRL_ENABLE; | 336 | ctrl |= ARCH_TIMER_CTRL_ENABLE; |
317 | ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; | 337 | ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; |
318 | 338 | ||
319 | if (access == ARCH_TIMER_PHYS_ACCESS) | 339 | if (access == ARCH_TIMER_PHYS_ACCESS) { |
340 | cval = evt + arch_counter_get_cntpct(); | ||
320 | write_sysreg(cval, cntp_cval_el0); | 341 | write_sysreg(cval, cntp_cval_el0); |
321 | else | 342 | } else { |
343 | cval = evt + arch_counter_get_cntvct(); | ||
322 | write_sysreg(cval, cntv_cval_el0); | 344 | write_sysreg(cval, cntv_cval_el0); |
345 | } | ||
323 | 346 | ||
324 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); | 347 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); |
325 | } | 348 | } |
@@ -346,6 +369,7 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { | |||
346 | .desc = "Freescale erratum a005858", | 369 | .desc = "Freescale erratum a005858", |
347 | .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0, | 370 | .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0, |
348 | .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0, | 371 | .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0, |
372 | .read_cntpct_el0 = fsl_a008585_read_cntpct_el0, | ||
349 | .read_cntvct_el0 = fsl_a008585_read_cntvct_el0, | 373 | .read_cntvct_el0 = fsl_a008585_read_cntvct_el0, |
350 | .set_next_event_phys = erratum_set_next_event_tval_phys, | 374 | .set_next_event_phys = erratum_set_next_event_tval_phys, |
351 | .set_next_event_virt = erratum_set_next_event_tval_virt, | 375 | .set_next_event_virt = erratum_set_next_event_tval_virt, |
@@ -358,6 +382,7 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { | |||
358 | .desc = "HiSilicon erratum 161010101", | 382 | .desc = "HiSilicon erratum 161010101", |
359 | .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, | 383 | .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, |
360 | .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, | 384 | .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, |
385 | .read_cntpct_el0 = hisi_161010101_read_cntpct_el0, | ||
361 | .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, | 386 | .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, |
362 | .set_next_event_phys = erratum_set_next_event_tval_phys, | 387 | .set_next_event_phys = erratum_set_next_event_tval_phys, |
363 | .set_next_event_virt = erratum_set_next_event_tval_virt, | 388 | .set_next_event_virt = erratum_set_next_event_tval_virt, |
@@ -368,6 +393,7 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { | |||
368 | .desc = "HiSilicon erratum 161010101", | 393 | .desc = "HiSilicon erratum 161010101", |
369 | .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, | 394 | .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, |
370 | .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, | 395 | .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, |
396 | .read_cntpct_el0 = hisi_161010101_read_cntpct_el0, | ||
371 | .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, | 397 | .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, |
372 | .set_next_event_phys = erratum_set_next_event_tval_phys, | 398 | .set_next_event_phys = erratum_set_next_event_tval_phys, |
373 | .set_next_event_virt = erratum_set_next_event_tval_virt, | 399 | .set_next_event_virt = erratum_set_next_event_tval_virt, |
@@ -378,6 +404,7 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { | |||
378 | .match_type = ate_match_local_cap_id, | 404 | .match_type = ate_match_local_cap_id, |
379 | .id = (void *)ARM64_WORKAROUND_858921, | 405 | .id = (void *)ARM64_WORKAROUND_858921, |
380 | .desc = "ARM erratum 858921", | 406 | .desc = "ARM erratum 858921", |
407 | .read_cntpct_el0 = arm64_858921_read_cntpct_el0, | ||
381 | .read_cntvct_el0 = arm64_858921_read_cntvct_el0, | 408 | .read_cntvct_el0 = arm64_858921_read_cntvct_el0, |
382 | }, | 409 | }, |
383 | #endif | 410 | #endif |
@@ -901,7 +928,7 @@ static void __init arch_counter_register(unsigned type) | |||
901 | 928 | ||
902 | /* Register the CP15 based counter if we have one */ | 929 | /* Register the CP15 based counter if we have one */ |
903 | if (type & ARCH_TIMER_TYPE_CP15) { | 930 | if (type & ARCH_TIMER_TYPE_CP15) { |
904 | if (IS_ENABLED(CONFIG_ARM64) || | 931 | if ((IS_ENABLED(CONFIG_ARM64) && !is_hyp_mode_available()) || |
905 | arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) | 932 | arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) |
906 | arch_timer_read_counter = arch_counter_get_cntvct; | 933 | arch_timer_read_counter = arch_counter_get_cntvct; |
907 | else | 934 | else |