aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2016-06-17 01:22:52 -0400
committerIngo Molnar <mingo@kernel.org>2016-07-11 15:30:13 -0400
commitff4c86635ee12461fd3bd911d7d5253394da8f9d (patch)
tree46d410019a232f2b0ecc89375d68abcfc27f565e /arch/x86/kernel
parentaa297292d708e89773b3b2cdcaf33f01bfa095d8 (diff)
x86/tsc: Enumerate BXT tsc_khz via CPUID
Hard code the BXT crystal clock (aka ART - Always Running Timer) to 19.200 MHz, and use CPUID leaf 0x15 to determine the BXT TSC frequency. Use tsc_khz to sanity check BXT cpu_khz, which can be erroneous in some configurations. (I simplified the original patch from Bin Gao.) Original-From: Bin Gao <bin.gao@intel.com> Signed-off-by: Len Brown <len.brown@intel.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/bf4e7c175acd6d09719c47c319b10ff1f0627ff8.1466138954.git.len.brown@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/tsc.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index e1496b79c28a..2a952fcb1516 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -693,7 +693,11 @@ unsigned long native_calibrate_tsc(void)
693 switch (boot_cpu_data.x86_model) { 693 switch (boot_cpu_data.x86_model) {
694 case 0x4E: /* SKL */ 694 case 0x4E: /* SKL */
695 case 0x5E: /* SKL */ 695 case 0x5E: /* SKL */
696 crystal_khz = 24000; /* 24 MHz */ 696 crystal_khz = 24000; /* 24.0 MHz */
697 break;
698 case 0x5C: /* BXT */
699 crystal_khz = 19200; /* 19.2 MHz */
700 break;
697 } 701 }
698 } 702 }
699 703
@@ -895,6 +899,8 @@ int recalibrate_cpu_khz(void)
895 tsc_khz = x86_platform.calibrate_tsc(); 899 tsc_khz = x86_platform.calibrate_tsc();
896 if (tsc_khz == 0) 900 if (tsc_khz == 0)
897 tsc_khz = cpu_khz; 901 tsc_khz = cpu_khz;
902 else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz)
903 cpu_khz = tsc_khz;
898 cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy, 904 cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy,
899 cpu_khz_old, cpu_khz); 905 cpu_khz_old, cpu_khz);
900 906
@@ -1302,8 +1308,16 @@ void __init tsc_init(void)
1302 1308
1303 cpu_khz = x86_platform.calibrate_cpu(); 1309 cpu_khz = x86_platform.calibrate_cpu();
1304 tsc_khz = x86_platform.calibrate_tsc(); 1310 tsc_khz = x86_platform.calibrate_tsc();
1311
1312 /*
1313 * Trust non-zero tsc_khz as authorative,
1314 * and use it to sanity check cpu_khz,
1315 * which will be off if system timer is off.
1316 */
1305 if (tsc_khz == 0) 1317 if (tsc_khz == 0)
1306 tsc_khz = cpu_khz; 1318 tsc_khz = cpu_khz;
1319 else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz)
1320 cpu_khz = tsc_khz;
1307 1321
1308 if (!tsc_khz) { 1322 if (!tsc_khz) {
1309 mark_tsc_unstable("could not calculate TSC khz"); 1323 mark_tsc_unstable("could not calculate TSC khz");