x86/tsc: Split native_calibrate_cpu() into early and late parts
During early boot TSC and CPU frequency can be calibrated using MSR, CPUID, and quick PIT calibration methods. The other methods PIT/HPET/PMTIMER are available only after ACPI is initialized. Split native_calibrate_cpu() into early and late parts so they can be called separately during early and late tsc calibration. Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: steven.sistare@oracle.com Cc: daniel.m.jordan@oracle.com Cc: linux@armlinux.org.uk Cc: schwidefsky@de.ibm.com Cc: heiko.carstens@de.ibm.com Cc: john.stultz@linaro.org Cc: sboyd@codeaurora.org Cc: hpa@zytor.com Cc: douly.fnst@cn.fujitsu.com Cc: peterz@infradead.org Cc: prarit@redhat.com Cc: feng.tang@intel.com Cc: pmladek@suse.com Cc: gnomes@lxorguk.ukuu.org.uk Cc: linux-s390@vger.kernel.org Cc: boris.ostrovsky@oracle.com Cc: jgross@suse.com Cc: pbonzini@redhat.com Link: https://lkml.kernel.org/r/20180719205545.16512-26-pasha.tatashin@oracle.com
This commit is contained in:
Родитель
46457ea464
Коммит
03821f451d
|
@ -40,6 +40,7 @@ extern int unsynchronized_tsc(void);
|
|||
extern int check_tsc_unstable(void);
|
||||
extern void mark_tsc_async_resets(char *reason);
|
||||
extern unsigned long native_calibrate_cpu(void);
|
||||
extern unsigned long native_calibrate_cpu_early(void);
|
||||
extern unsigned long native_calibrate_tsc(void);
|
||||
extern unsigned long long native_sched_clock_from_tsc(u64 tsc);
|
||||
|
||||
|
|
|
@ -680,30 +680,17 @@ static unsigned long cpu_khz_from_cpuid(void)
|
|||
return eax_base_mhz * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* native_calibrate_cpu - calibrate the cpu on boot
|
||||
/*
|
||||
* calibrate cpu using pit, hpet, and ptimer methods. They are available
|
||||
* later in boot after acpi is initialized.
|
||||
*/
|
||||
unsigned long native_calibrate_cpu(void)
|
||||
static unsigned long pit_hpet_ptimer_calibrate_cpu(void)
|
||||
{
|
||||
u64 tsc1, tsc2, delta, ref1, ref2;
|
||||
unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
|
||||
unsigned long flags, latch, ms, fast_calibrate;
|
||||
unsigned long flags, latch, ms;
|
||||
int hpet = is_hpet_enabled(), i, loopmin;
|
||||
|
||||
fast_calibrate = cpu_khz_from_cpuid();
|
||||
if (fast_calibrate)
|
||||
return fast_calibrate;
|
||||
|
||||
fast_calibrate = cpu_khz_from_msr();
|
||||
if (fast_calibrate)
|
||||
return fast_calibrate;
|
||||
|
||||
local_irq_save(flags);
|
||||
fast_calibrate = quick_pit_calibrate();
|
||||
local_irq_restore(flags);
|
||||
if (fast_calibrate)
|
||||
return fast_calibrate;
|
||||
|
||||
/*
|
||||
* Run 5 calibration loops to get the lowest frequency value
|
||||
* (the best estimate). We use two different calibration modes
|
||||
|
@ -846,6 +833,37 @@ unsigned long native_calibrate_cpu(void)
|
|||
return tsc_pit_min;
|
||||
}
|
||||
|
||||
/**
|
||||
* native_calibrate_cpu_early - can calibrate the cpu early in boot
|
||||
*/
|
||||
unsigned long native_calibrate_cpu_early(void)
|
||||
{
|
||||
unsigned long flags, fast_calibrate = cpu_khz_from_cpuid();
|
||||
|
||||
if (!fast_calibrate)
|
||||
fast_calibrate = cpu_khz_from_msr();
|
||||
if (!fast_calibrate) {
|
||||
local_irq_save(flags);
|
||||
fast_calibrate = quick_pit_calibrate();
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
return fast_calibrate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* native_calibrate_cpu - calibrate the cpu
|
||||
*/
|
||||
unsigned long native_calibrate_cpu(void)
|
||||
{
|
||||
unsigned long tsc_freq = native_calibrate_cpu_early();
|
||||
|
||||
if (!tsc_freq)
|
||||
tsc_freq = pit_hpet_ptimer_calibrate_cpu();
|
||||
|
||||
return tsc_freq;
|
||||
}
|
||||
|
||||
void recalibrate_cpu_khz(void)
|
||||
{
|
||||
#ifndef CONFIG_SMP
|
||||
|
|
Загрузка…
Ссылка в новой задаче