aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-08-25 01:41:26 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:53:03 -0400
commite492c5ae85428d4a3815d06bf308c590120b928b (patch)
treedd452cb7455e001221b60b07bb4ef3020531b1a1 /arch
parent0f611ffaea81b8e1c69682188ba1ccaf7683a2ba (diff)
x86: let 64 bit to use 32 bit calibrate_apic_clock
Use the 32-bit APIC calibration code - it's more mature. Signed-of-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/apic.c88
1 files changed, 2 insertions, 86 deletions
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index 6e99af5ce678..ca5ef71f4208 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -478,90 +478,6 @@ static void __cpuinit setup_APIC_timer(void)
478 clockevents_register_device(levt); 478 clockevents_register_device(levt);
479} 479}
480 480
481#ifdef CONFIG_X86_64
482/*
483 * In this function we calibrate APIC bus clocks to the external
484 * timer. Unfortunately we cannot use jiffies and the timer irq
485 * to calibrate, since some later bootup code depends on getting
486 * the first irq? Ugh.
487 *
488 * We want to do the calibration only once since we
489 * want to have local timer irqs syncron. CPUs connected
490 * by the same APIC bus have the very same bus frequency.
491 * And we want to have irqs off anyways, no accidental
492 * APIC irq that way.
493 */
494
495#define TICK_COUNT 100000000
496
497static int __init calibrate_APIC_clock(void)
498{
499 unsigned apic, apic_start;
500 unsigned long tsc, tsc_start;
501 int result;
502
503 local_irq_disable();
504
505 /*
506 * Put whatever arbitrary (but long enough) timeout
507 * value into the APIC clock, we just want to get the
508 * counter running for calibration.
509 *
510 * No interrupt enable !
511 */
512 __setup_APIC_LVTT(250000000, 0, 0);
513
514 apic_start = apic_read(APIC_TMCCT);
515#ifdef CONFIG_X86_PM_TIMER
516 if (apic_calibrate_pmtmr && pmtmr_ioport) {
517 pmtimer_wait(5000); /* 5ms wait */
518 apic = apic_read(APIC_TMCCT);
519 result = (apic_start - apic) * 1000L / 5;
520 } else
521#endif
522 {
523 rdtscll(tsc_start);
524
525 do {
526 apic = apic_read(APIC_TMCCT);
527 rdtscll(tsc);
528 } while ((tsc - tsc_start) < TICK_COUNT &&
529 (apic_start - apic) < TICK_COUNT);
530
531 result = (apic_start - apic) * 1000L * tsc_khz /
532 (tsc - tsc_start);
533 }
534
535 local_irq_enable();
536
537 printk(KERN_DEBUG "APIC timer calibration result %d\n", result);
538
539 printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
540 result / 1000 / 1000, result / 1000 % 1000);
541
542 /* Calculate the scaled math multiplication factor */
543 lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC,
544 lapic_clockevent.shift);
545 lapic_clockevent.max_delta_ns =
546 clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
547 lapic_clockevent.min_delta_ns =
548 clockevent_delta2ns(0xF, &lapic_clockevent);
549
550 calibration_result = (result * APIC_DIVISOR) / HZ;
551
552 /*
553 * Do a sanity check on the APIC calibration result
554 */
555 if (calibration_result < (1000000 / HZ)) {
556 printk(KERN_WARNING
557 "APIC frequency too slow, disabling apic timer\n");
558 return -1;
559 }
560
561 return 0;
562}
563
564#else
565/* 481/*
566 * In this functions we calibrate APIC bus clocks to the external timer. 482 * In this functions we calibrate APIC bus clocks to the external timer.
567 * 483 *
@@ -659,6 +575,7 @@ static int __init calibrate_APIC_clock(void)
659 delta = lapic_cal_t1 - lapic_cal_t2; 575 delta = lapic_cal_t1 - lapic_cal_t2;
660 apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta); 576 apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);
661 577
578#ifdef CONFIG_X86_PM_TIMER
662 /* Check, if the PM timer is available */ 579 /* Check, if the PM timer is available */
663 deltapm = lapic_cal_pm2 - lapic_cal_pm1; 580 deltapm = lapic_cal_pm2 - lapic_cal_pm1;
664 apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm); 581 apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
@@ -687,6 +604,7 @@ static int __init calibrate_APIC_clock(void)
687 } 604 }
688 pm_referenced = 1; 605 pm_referenced = 1;
689 } 606 }
607#endif
690 608
691 /* Calculate the scaled math multiplication factor */ 609 /* Calculate the scaled math multiplication factor */
692 lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, 610 lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
@@ -773,8 +691,6 @@ static int __init calibrate_APIC_clock(void)
773 return 0; 691 return 0;
774} 692}
775 693
776#endif
777
778/* 694/*
779 * Setup the boot APIC 695 * Setup the boot APIC
780 * 696 *