aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/arm_arch_timer.c
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-02-20 10:21:23 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2016-02-29 13:34:16 -0500
commitf81f03fa231a8c3aacd580759e73b9238b92ba29 (patch)
tree475b6e0b10543fb9f2cd92ee78382ed1392a182d /drivers/clocksource/arm_arch_timer.c
parent82deae0fc8ba256c1061dd4de42f0ef6cb9f954f (diff)
arm64: Allow the arch timer to use the HYP timer
With the ARMv8.1 VHE, the kernel can run in HYP mode, and thus use the HYP timer instead of the normal guest timer in a mostly transparent way, except for the interrupt line. This patch reworks the arch timer code to allow the selection of the HYP PPI, possibly falling back to the guest timer if not available. Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'drivers/clocksource/arm_arch_timer.c')
-rw-r--r--drivers/clocksource/arm_arch_timer.c96
1 files changed, 59 insertions, 37 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index c64d543d64bf..ffe9d1c6b588 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -67,7 +67,7 @@ static int arch_timer_ppi[MAX_TIMER_PPI];
67 67
68static struct clock_event_device __percpu *arch_timer_evt; 68static struct clock_event_device __percpu *arch_timer_evt;
69 69
70static bool arch_timer_use_virtual = true; 70static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI;
71static bool arch_timer_c3stop; 71static bool arch_timer_c3stop;
72static bool arch_timer_mem_use_virtual; 72static bool arch_timer_mem_use_virtual;
73 73
@@ -263,14 +263,20 @@ static void __arch_timer_setup(unsigned type,
263 clk->name = "arch_sys_timer"; 263 clk->name = "arch_sys_timer";
264 clk->rating = 450; 264 clk->rating = 450;
265 clk->cpumask = cpumask_of(smp_processor_id()); 265 clk->cpumask = cpumask_of(smp_processor_id());
266 if (arch_timer_use_virtual) { 266 clk->irq = arch_timer_ppi[arch_timer_uses_ppi];
267 clk->irq = arch_timer_ppi[VIRT_PPI]; 267 switch (arch_timer_uses_ppi) {
268 case VIRT_PPI:
268 clk->set_state_shutdown = arch_timer_shutdown_virt; 269 clk->set_state_shutdown = arch_timer_shutdown_virt;
269 clk->set_next_event = arch_timer_set_next_event_virt; 270 clk->set_next_event = arch_timer_set_next_event_virt;
270 } else { 271 break;
271 clk->irq = arch_timer_ppi[PHYS_SECURE_PPI]; 272 case PHYS_SECURE_PPI:
273 case PHYS_NONSECURE_PPI:
274 case HYP_PPI:
272 clk->set_state_shutdown = arch_timer_shutdown_phys; 275 clk->set_state_shutdown = arch_timer_shutdown_phys;
273 clk->set_next_event = arch_timer_set_next_event_phys; 276 clk->set_next_event = arch_timer_set_next_event_phys;
277 break;
278 default:
279 BUG();
274 } 280 }
275 } else { 281 } else {
276 clk->features |= CLOCK_EVT_FEAT_DYNIRQ; 282 clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
@@ -338,17 +344,20 @@ static void arch_counter_set_user_access(void)
338 arch_timer_set_cntkctl(cntkctl); 344 arch_timer_set_cntkctl(cntkctl);
339} 345}
340 346
347static bool arch_timer_has_nonsecure_ppi(void)
348{
349 return (arch_timer_uses_ppi == PHYS_SECURE_PPI &&
350 arch_timer_ppi[PHYS_NONSECURE_PPI]);
351}
352
341static int arch_timer_setup(struct clock_event_device *clk) 353static int arch_timer_setup(struct clock_event_device *clk)
342{ 354{
343 __arch_timer_setup(ARCH_CP15_TIMER, clk); 355 __arch_timer_setup(ARCH_CP15_TIMER, clk);
344 356
345 if (arch_timer_use_virtual) 357 enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], 0);
346 enable_percpu_irq(arch_timer_ppi[VIRT_PPI], 0); 358
347 else { 359 if (arch_timer_has_nonsecure_ppi())
348 enable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], 0); 360 enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0);
349 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
350 enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0);
351 }
352 361
353 arch_counter_set_user_access(); 362 arch_counter_set_user_access();
354 if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM)) 363 if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM))
@@ -390,7 +399,7 @@ static void arch_timer_banner(unsigned type)
390 (unsigned long)arch_timer_rate / 1000000, 399 (unsigned long)arch_timer_rate / 1000000,
391 (unsigned long)(arch_timer_rate / 10000) % 100, 400 (unsigned long)(arch_timer_rate / 10000) % 100,
392 type & ARCH_CP15_TIMER ? 401 type & ARCH_CP15_TIMER ?
393 arch_timer_use_virtual ? "virt" : "phys" : 402 (arch_timer_uses_ppi == VIRT_PPI) ? "virt" : "phys" :
394 "", 403 "",
395 type == (ARCH_CP15_TIMER | ARCH_MEM_TIMER) ? "/" : "", 404 type == (ARCH_CP15_TIMER | ARCH_MEM_TIMER) ? "/" : "",
396 type & ARCH_MEM_TIMER ? 405 type & ARCH_MEM_TIMER ?
@@ -460,7 +469,7 @@ static void __init arch_counter_register(unsigned type)
460 469
461 /* Register the CP15 based counter if we have one */ 470 /* Register the CP15 based counter if we have one */
462 if (type & ARCH_CP15_TIMER) { 471 if (type & ARCH_CP15_TIMER) {
463 if (IS_ENABLED(CONFIG_ARM64) || arch_timer_use_virtual) 472 if (IS_ENABLED(CONFIG_ARM64) || arch_timer_uses_ppi == VIRT_PPI)
464 arch_timer_read_counter = arch_counter_get_cntvct; 473 arch_timer_read_counter = arch_counter_get_cntvct;
465 else 474 else
466 arch_timer_read_counter = arch_counter_get_cntpct; 475 arch_timer_read_counter = arch_counter_get_cntpct;
@@ -490,13 +499,9 @@ static void arch_timer_stop(struct clock_event_device *clk)
490 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", 499 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
491 clk->irq, smp_processor_id()); 500 clk->irq, smp_processor_id());
492 501
493 if (arch_timer_use_virtual) 502 disable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi]);
494 disable_percpu_irq(arch_timer_ppi[VIRT_PPI]); 503 if (arch_timer_has_nonsecure_ppi())
495 else { 504 disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
496 disable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI]);
497 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
498 disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
499 }
500 505
501 clk->set_state_shutdown(clk); 506 clk->set_state_shutdown(clk);
502} 507}
@@ -562,12 +567,14 @@ static int __init arch_timer_register(void)
562 goto out; 567 goto out;
563 } 568 }
564 569
565 if (arch_timer_use_virtual) { 570 ppi = arch_timer_ppi[arch_timer_uses_ppi];
566 ppi = arch_timer_ppi[VIRT_PPI]; 571 switch (arch_timer_uses_ppi) {
572 case VIRT_PPI:
567 err = request_percpu_irq(ppi, arch_timer_handler_virt, 573 err = request_percpu_irq(ppi, arch_timer_handler_virt,
568 "arch_timer", arch_timer_evt); 574 "arch_timer", arch_timer_evt);
569 } else { 575 break;
570 ppi = arch_timer_ppi[PHYS_SECURE_PPI]; 576 case PHYS_SECURE_PPI:
577 case PHYS_NONSECURE_PPI:
571 err = request_percpu_irq(ppi, arch_timer_handler_phys, 578 err = request_percpu_irq(ppi, arch_timer_handler_phys,
572 "arch_timer", arch_timer_evt); 579 "arch_timer", arch_timer_evt);
573 if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) { 580 if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) {
@@ -578,6 +585,13 @@ static int __init arch_timer_register(void)
578 free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], 585 free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
579 arch_timer_evt); 586 arch_timer_evt);
580 } 587 }
588 break;
589 case HYP_PPI:
590 err = request_percpu_irq(ppi, arch_timer_handler_phys,
591 "arch_timer", arch_timer_evt);
592 break;
593 default:
594 BUG();
581 } 595 }
582 596
583 if (err) { 597 if (err) {
@@ -602,15 +616,10 @@ static int __init arch_timer_register(void)
602out_unreg_notify: 616out_unreg_notify:
603 unregister_cpu_notifier(&arch_timer_cpu_nb); 617 unregister_cpu_notifier(&arch_timer_cpu_nb);
604out_free_irq: 618out_free_irq:
605 if (arch_timer_use_virtual) 619 free_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], arch_timer_evt);
606 free_percpu_irq(arch_timer_ppi[VIRT_PPI], arch_timer_evt); 620 if (arch_timer_has_nonsecure_ppi())
607 else { 621 free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],
608 free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
609 arch_timer_evt); 622 arch_timer_evt);
610 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
611 free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],
612 arch_timer_evt);
613 }
614 623
615out_free: 624out_free:
616 free_percpu(arch_timer_evt); 625 free_percpu(arch_timer_evt);
@@ -697,12 +706,25 @@ static void __init arch_timer_init(void)
697 * 706 *
698 * If no interrupt provided for virtual timer, we'll have to 707 * If no interrupt provided for virtual timer, we'll have to
699 * stick to the physical timer. It'd better be accessible... 708 * stick to the physical timer. It'd better be accessible...
709 *
710 * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
711 * accesses to CNTP_*_EL1 registers are silently redirected to
712 * their CNTHP_*_EL2 counterparts, and use a different PPI
713 * number.
700 */ 714 */
701 if (is_hyp_mode_available() || !arch_timer_ppi[VIRT_PPI]) { 715 if (is_hyp_mode_available() || !arch_timer_ppi[VIRT_PPI]) {
702 arch_timer_use_virtual = false; 716 bool has_ppi;
717
718 if (is_kernel_in_hyp_mode()) {
719 arch_timer_uses_ppi = HYP_PPI;
720 has_ppi = !!arch_timer_ppi[HYP_PPI];
721 } else {
722 arch_timer_uses_ppi = PHYS_SECURE_PPI;
723 has_ppi = (!!arch_timer_ppi[PHYS_SECURE_PPI] ||
724 !!arch_timer_ppi[PHYS_NONSECURE_PPI]);
725 }
703 726
704 if (!arch_timer_ppi[PHYS_SECURE_PPI] || 727 if (!has_ppi) {
705 !arch_timer_ppi[PHYS_NONSECURE_PPI]) {
706 pr_warn("arch_timer: No interrupt available, giving up\n"); 728 pr_warn("arch_timer: No interrupt available, giving up\n");
707 return; 729 return;
708 } 730 }
@@ -735,7 +757,7 @@ static void __init arch_timer_of_init(struct device_node *np)
735 */ 757 */
736 if (IS_ENABLED(CONFIG_ARM) && 758 if (IS_ENABLED(CONFIG_ARM) &&
737 of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) 759 of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
738 arch_timer_use_virtual = false; 760 arch_timer_uses_ppi = PHYS_SECURE_PPI;
739 761
740 arch_timer_init(); 762 arch_timer_init();
741} 763}