mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
Add support for ACPI PM Timer as platform clock source.
Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
603d6a3905
commit
dc059c5b49
2 files changed
+56
-1
No files matched your search
+55
-1
@@ -510,6 +510,60 @@ static int init_cyclone(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* PLATFORM TIMER 4: ACPI PM TIMER
|
||||
*/
|
||||
|
||||
u32 pmtmr_ioport;
|
||||
|
||||
/* Protected by platform_timer_lock. */
|
||||
static u64 pmtimer_counter64;
|
||||
static u32 pmtimer_stamp;
|
||||
static struct timer pmtimer_overflow_timer;
|
||||
|
||||
/* ACPI PM timer ticks at 3.579545 MHz. */
|
||||
#define ACPI_PM_FREQUENCY 3579545
|
||||
|
||||
/* Deltas are 24-bit unsigned values, as counter may be only 24 bits wide. */
|
||||
#define pmtimer_delta(c) ((u32)(((c) - pmtimer_stamp) & ((1U<<24)-1)))
|
||||
|
||||
static void pmtimer_overflow(void *unused)
|
||||
{
|
||||
u32 counter;
|
||||
|
||||
spin_lock_irq(&platform_timer_lock);
|
||||
counter = inl(pmtmr_ioport);
|
||||
pmtimer_counter64 += pmtimer_delta(counter);
|
||||
pmtimer_stamp = counter;
|
||||
spin_unlock_irq(&platform_timer_lock);
|
||||
|
||||
/* Trigger overflow avoidance roughly when counter increments 2^23. */
|
||||
set_timer(&pmtimer_overflow_timer, NOW() + MILLISECS(2000));
|
||||
}
|
||||
|
||||
static u64 read_pmtimer_count(void)
|
||||
{
|
||||
return pmtimer_counter64 + pmtimer_delta(inl(pmtmr_ioport));
|
||||
}
|
||||
|
||||
static int init_pmtimer(void)
|
||||
{
|
||||
if ( pmtmr_ioport == 0 )
|
||||
return 0;
|
||||
|
||||
read_platform_count = read_pmtimer_count;
|
||||
|
||||
init_timer(&pmtimer_overflow_timer, pmtimer_overflow, NULL, 0);
|
||||
pmtimer_overflow(NULL);
|
||||
platform_timer_stamp = pmtimer_counter64;
|
||||
set_time_scale(&platform_timer_scale, ACPI_PM_FREQUENCY);
|
||||
|
||||
printk("Platform timer is %s ACPI PM Timer\n",
|
||||
freq_string(ACPI_PM_FREQUENCY));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* GENERIC PLATFORM TIMER INFRASTRUCTURE
|
||||
*/
|
||||
@@ -549,7 +603,7 @@ static void platform_time_calibration(void)
|
||||
|
||||
static void init_platform_timer(void)
|
||||
{
|
||||
if ( !init_cyclone() && !init_hpet() )
|
||||
if ( !init_cyclone() && !init_hpet() && !init_pmtimer() )
|
||||
init_pit();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define CONFIG_X86_LOCAL_APIC 1
|
||||
#define CONFIG_X86_GOOD_APIC 1
|
||||
#define CONFIG_X86_IO_APIC 1
|
||||
#define CONFIG_X86_PM_TIMER 1
|
||||
#define CONFIG_HPET_TIMER 1
|
||||
#define CONFIG_X86_MCE_P4THERMAL 1
|
||||
#define CONFIG_ACPI_NUMA 1
|
||||
|
||||