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 fd4b7f684bd0..061476e92db7 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -158,6 +158,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, | |||
158 | * if we don't have the cp15 accessors we won't have a problem. | 158 | * if we don't have the cp15 accessors we won't have a problem. |
159 | */ | 159 | */ |
160 | u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct; | 160 | u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct; |
161 | EXPORT_SYMBOL_GPL(arch_timer_read_counter); | ||
161 | 162 | ||
162 | static u64 arch_counter_read(struct clocksource *cs) | 163 | static u64 arch_counter_read(struct clocksource *cs) |
163 | { | 164 | { |
@@ -217,6 +218,11 @@ static u32 notrace fsl_a008585_read_cntv_tval_el0(void) | |||
217 | return __fsl_a008585_read_reg(cntv_tval_el0); | 218 | return __fsl_a008585_read_reg(cntv_tval_el0); |
218 | } | 219 | } |
219 | 220 | ||
221 | static u64 notrace fsl_a008585_read_cntpct_el0(void) | ||
222 | { | ||
223 | return __fsl_a008585_read_reg(cntpct_el0); | ||
224 | } | ||
225 | |||
220 | static u64 notrace fsl_a008585_read_cntvct_el0(void) | 226 | static u64 notrace fsl_a008585_read_cntvct_el0(void) |
221 | { | 227 | { |
222 | return __fsl_a008585_read_reg(cntvct_el0); | 228 | return __fsl_a008585_read_reg(cntvct_el0); |
@@ -258,6 +264,11 @@ static u32 notrace hisi_161010101_read_cntv_tval_el0(void) | |||
258 | return __hisi_161010101_read_reg(cntv_tval_el0); | 264 | return __hisi_161010101_read_reg(cntv_tval_el0); |
259 | } | 265 | } |
260 | 266 | ||
267 | static u64 notrace hisi_161010101_read_cntpct_el0(void) | ||
268 | { | ||
269 | return __hisi_161010101_read_reg(cntpct_el0); | ||
270 | } | ||
271 | |||
261 | static u64 notrace hisi_161010101_read_cntvct_el0(void) | 272 | static u64 notrace hisi_161010101_read_cntvct_el0(void) |
262 | { | 273 | { |
263 | return __hisi_161010101_read_reg(cntvct_el0); | 274 | return __hisi_161010101_read_reg(cntvct_el0); |
@@ -288,6 +299,15 @@ static struct ate_acpi_oem_info hisi_161010101_oem_info[] = { | |||
288 | #endif | 299 | #endif |
289 | 300 | ||
290 | #ifdef CONFIG_ARM64_ERRATUM_858921 | 301 | #ifdef CONFIG_ARM64_ERRATUM_858921 |
302 | static u64 notrace arm64_858921_read_cntpct_el0(void) | ||
303 | { | ||
304 | u64 old, new; | ||
305 | |||
306 | old = read_sysreg(cntpct_el0); | ||
307 | new = read_sysreg(cntpct_el0); | ||
308 | return (((old ^ new) >> 32) & 1) ? old : new; | ||
309 | } | ||
310 | |||
291 | static u64 notrace arm64_858921_read_cntvct_el0(void) | 311 | static u64 notrace arm64_858921_read_cntvct_el0(void) |
292 | { | 312 | { |
293 | u64 old, new; | 313 | 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 |
@@ -890,7 +917,7 @@ static void __init arch_counter_register(unsigned type) | |||
890 | 917 | ||
891 | /* Register the CP15 based counter if we have one */ | 918 | /* Register the CP15 based counter if we have one */ |
892 | if (type & ARCH_TIMER_TYPE_CP15) { | 919 | if (type & ARCH_TIMER_TYPE_CP15) { |
893 | if (IS_ENABLED(CONFIG_ARM64) || | 920 | if ((IS_ENABLED(CONFIG_ARM64) && !is_hyp_mode_available()) || |
894 | arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) | 921 | arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) |
895 | arch_timer_read_counter = arch_counter_get_cntvct; | 922 | arch_timer_read_counter = arch_counter_get_cntvct; |
896 | else | 923 | else |