Commit 03821f45 authored by Pavel Tatashin's avatar Pavel Tatashin Committed by Thomas Gleixner

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: default avatarPavel Tatashin <pasha.tatashin@oracle.com>
Signed-off-by: default avatarThomas 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
parent 46457ea4
...@@ -40,6 +40,7 @@ extern int unsynchronized_tsc(void); ...@@ -40,6 +40,7 @@ extern int unsynchronized_tsc(void);
extern int check_tsc_unstable(void); extern int check_tsc_unstable(void);
extern void mark_tsc_async_resets(char *reason); extern void mark_tsc_async_resets(char *reason);
extern unsigned long native_calibrate_cpu(void); 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 native_calibrate_tsc(void);
extern unsigned long long native_sched_clock_from_tsc(u64 tsc); extern unsigned long long native_sched_clock_from_tsc(u64 tsc);
......
...@@ -680,30 +680,17 @@ static unsigned long cpu_khz_from_cpuid(void) ...@@ -680,30 +680,17 @@ static unsigned long cpu_khz_from_cpuid(void)
return eax_base_mhz * 1000; 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; u64 tsc1, tsc2, delta, ref1, ref2;
unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX; 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; 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 * Run 5 calibration loops to get the lowest frequency value
* (the best estimate). We use two different calibration modes * (the best estimate). We use two different calibration modes
...@@ -846,6 +833,37 @@ unsigned long native_calibrate_cpu(void) ...@@ -846,6 +833,37 @@ unsigned long native_calibrate_cpu(void)
return tsc_pit_min; 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) void recalibrate_cpu_khz(void)
{ {
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment