ia64/xen-unstable

changeset 15244:2d7d33ac982a

Add support for ACPI PM Timer as platform clock source.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed May 30 18:12:02 2007 +0100 (2007-05-30)
parents ae073ca6eb76
children c9d66baad22b
files xen/arch/x86/time.c xen/include/asm-x86/config.h
line diff
     1.1 --- a/xen/arch/x86/time.c	Wed May 30 17:47:00 2007 +0100
     1.2 +++ b/xen/arch/x86/time.c	Wed May 30 18:12:02 2007 +0100
     1.3 @@ -511,6 +511,60 @@ static int init_cyclone(void)
     1.4  }
     1.5  
     1.6  /************************************************************
     1.7 + * PLATFORM TIMER 4: ACPI PM TIMER
     1.8 + */
     1.9 +
    1.10 +u32 pmtmr_ioport;
    1.11 +
    1.12 +/* Protected by platform_timer_lock. */
    1.13 +static u64 pmtimer_counter64;
    1.14 +static u32 pmtimer_stamp;
    1.15 +static struct timer pmtimer_overflow_timer;
    1.16 +
    1.17 +/* ACPI PM timer ticks at 3.579545 MHz. */
    1.18 +#define ACPI_PM_FREQUENCY 3579545
    1.19 +
    1.20 +/* Deltas are 24-bit unsigned values, as counter may be only 24 bits wide. */
    1.21 +#define pmtimer_delta(c) ((u32)(((c) - pmtimer_stamp) & ((1U<<24)-1)))
    1.22 +
    1.23 +static void pmtimer_overflow(void *unused)
    1.24 +{
    1.25 +    u32 counter;
    1.26 +
    1.27 +    spin_lock_irq(&platform_timer_lock);
    1.28 +    counter = inl(pmtmr_ioport);
    1.29 +    pmtimer_counter64 += pmtimer_delta(counter);
    1.30 +    pmtimer_stamp = counter;
    1.31 +    spin_unlock_irq(&platform_timer_lock);
    1.32 +
    1.33 +    /* Trigger overflow avoidance roughly when counter increments 2^23. */
    1.34 +    set_timer(&pmtimer_overflow_timer, NOW() + MILLISECS(2000));
    1.35 +}
    1.36 +
    1.37 +static u64 read_pmtimer_count(void)
    1.38 +{
    1.39 +    return pmtimer_counter64 + pmtimer_delta(inl(pmtmr_ioport));
    1.40 +}
    1.41 +
    1.42 +static int init_pmtimer(void)
    1.43 +{
    1.44 +    if ( pmtmr_ioport == 0 )
    1.45 +        return 0;
    1.46 +
    1.47 +    read_platform_count = read_pmtimer_count;
    1.48 +
    1.49 +    init_timer(&pmtimer_overflow_timer, pmtimer_overflow, NULL, 0);
    1.50 +    pmtimer_overflow(NULL);
    1.51 +    platform_timer_stamp = pmtimer_counter64;
    1.52 +    set_time_scale(&platform_timer_scale, ACPI_PM_FREQUENCY);
    1.53 +
    1.54 +    printk("Platform timer is %s ACPI PM Timer\n",
    1.55 +           freq_string(ACPI_PM_FREQUENCY));
    1.56 +
    1.57 +    return 1;
    1.58 +}
    1.59 +
    1.60 +/************************************************************
    1.61   * GENERIC PLATFORM TIMER INFRASTRUCTURE
    1.62   */
    1.63  
    1.64 @@ -549,7 +603,7 @@ static void platform_time_calibration(vo
    1.65  
    1.66  static void init_platform_timer(void)
    1.67  {
    1.68 -    if ( !init_cyclone() && !init_hpet() )
    1.69 +    if ( !init_cyclone() && !init_hpet() && !init_pmtimer() )
    1.70          init_pit();
    1.71  }
    1.72  
     2.1 --- a/xen/include/asm-x86/config.h	Wed May 30 17:47:00 2007 +0100
     2.2 +++ b/xen/include/asm-x86/config.h	Wed May 30 18:12:02 2007 +0100
     2.3 @@ -22,6 +22,7 @@
     2.4  #define CONFIG_X86_LOCAL_APIC 1
     2.5  #define CONFIG_X86_GOOD_APIC 1
     2.6  #define CONFIG_X86_IO_APIC 1
     2.7 +#define CONFIG_X86_PM_TIMER 1
     2.8  #define CONFIG_HPET_TIMER 1
     2.9  #define CONFIG_X86_MCE_P4THERMAL 1
    2.10  #define CONFIG_ACPI_NUMA 1