Merge branch 'x86-cleanups-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / arch / x86 / kernel / tsc.c
index 75a41bddbc9d779fffccbb68ce577aa1106e17cb..57d87f79558f2306ebc3415ad4d78740e3d97784 100644 (file)
@@ -632,31 +632,38 @@ unsigned long native_calibrate_tsc(void)
 
        crystal_khz = ecx_hz / 1000;
 
-       if (crystal_khz == 0) {
-               switch (boot_cpu_data.x86_model) {
-               case INTEL_FAM6_SKYLAKE_MOBILE:
-               case INTEL_FAM6_SKYLAKE_DESKTOP:
-               case INTEL_FAM6_KABYLAKE_MOBILE:
-               case INTEL_FAM6_KABYLAKE_DESKTOP:
-                       crystal_khz = 24000;    /* 24.0 MHz */
-                       break;
-               case INTEL_FAM6_ATOM_GOLDMONT_X:
-                       crystal_khz = 25000;    /* 25.0 MHz */
-                       break;
-               case INTEL_FAM6_ATOM_GOLDMONT:
-                       crystal_khz = 19200;    /* 19.2 MHz */
-                       break;
-               }
-       }
+       /*
+        * Denverton SoCs don't report crystal clock, and also don't support
+        * CPUID.0x16 for the calculation below, so hardcode the 25MHz crystal
+        * clock.
+        */
+       if (crystal_khz == 0 &&
+                       boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT_X)
+               crystal_khz = 25000;
 
-       if (crystal_khz == 0)
-               return 0;
        /*
-        * TSC frequency determined by CPUID is a "hardware reported"
+        * TSC frequency reported directly by CPUID is a "hardware reported"
         * frequency and is the most accurate one so far we have. This
         * is considered a known frequency.
         */
-       setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+       if (crystal_khz != 0)
+               setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+       /*
+        * Some Intel SoCs like Skylake and Kabylake don't report the crystal
+        * clock, but we can easily calculate it to a high degree of accuracy
+        * by considering the crystal ratio and the CPU speed.
+        */
+       if (crystal_khz == 0 && boot_cpu_data.cpuid_level >= 0x16) {
+               unsigned int eax_base_mhz, ebx, ecx, edx;
+
+               cpuid(0x16, &eax_base_mhz, &ebx, &ecx, &edx);
+               crystal_khz = eax_base_mhz * 1000 *
+                       eax_denominator / ebx_numerator;
+       }
+
+       if (crystal_khz == 0)
+               return 0;
 
        /*
         * For Atom SoCs TSC is the only reliable clocksource.
@@ -665,6 +672,16 @@ unsigned long native_calibrate_tsc(void)
        if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
                setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
+#ifdef CONFIG_X86_LOCAL_APIC
+       /*
+        * The local APIC appears to be fed by the core crystal clock
+        * (which sounds entirely sensible). We can set the global
+        * lapic_timer_period here to avoid having to calibrate the APIC
+        * timer later.
+        */
+       lapic_timer_period = crystal_khz * 1000 / HZ;
+#endif
+
        return crystal_khz * ebx_numerator / eax_denominator;
 }