diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-08-25 01:41:26 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:53:03 -0400 |
commit | e492c5ae85428d4a3815d06bf308c590120b928b (patch) | |
tree | dd452cb7455e001221b60b07bb4ef3020531b1a1 /arch | |
parent | 0f611ffaea81b8e1c69682188ba1ccaf7683a2ba (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.c | 88 |
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 | |||
497 | static 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 | * |