x86/tsc: Set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs
authorBin Gao <bin.gao@linux.intel.com>
Tue, 15 Nov 2016 20:27:24 +0000 (12:27 -0800)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 18 Nov 2016 09:58:31 +0000 (10:58 +0100)
TSC on Intel Atom SoCs capable of determining TSC frequency by MSR is
reliable and the frequency is known (provided by HW).

On these platforms PIT/HPET is generally not available so calibration won't
work at all and there is no other clocksource to act as a watchdog for the
TSC, so we have no other choice than to trust it.

Set both X86_FEATURE_TSC_KNOWN_FREQ and X86_FEATURE_TSC_RELIABLE flags to
make sure the calibration is skipped and no watchdog is required.

Signed-off-by: Bin Gao <bin.gao@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1479241644-234277-5-git-send-email-bin.gao@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/kernel/tsc_msr.c
arch/x86/platform/intel-mid/mfld.c
arch/x86/platform/intel-mid/mrfld.c

index 0fe720d64feff2c7027280f741495f6a9cf4722c..19afdbd7d0a77c8f5511cf2de616d24c5259dbae 100644 (file)
@@ -100,5 +100,24 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
        lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+       /*
+        * TSC frequency determined by MSR is always considered "known"
+        * because it is reported by HW.
+        * Another fact is that on MSR capable platforms, PIT/HPET is
+        * generally not available so calibration won't work at all.
+        */
+       setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+       /*
+        * Unfortunately there is no way for hardware to tell whether the
+        * TSC is reliable.  We were told by silicon design team that TSC
+        * on Atom SoCs are always "reliable". TSC is also the only
+        * reliable clocksource on these SoCs (HPET is either not present
+        * or not functional) so mark TSC reliable which removes the
+        * requirement for a watchdog clocksource.
+        */
+       setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
        return res;
 }
index 1eb47b6298c20fc20ae6de0c2f9f3762854286cc..e793fe509971f49fb2cfa6a12f8b365a937ae206 100644 (file)
@@ -49,8 +49,13 @@ static unsigned long __init mfld_calibrate_tsc(void)
        fast_calibrate = ratio * fsb;
        pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
        lapic_timer_frequency = fsb * 1000 / HZ;
-       /* mark tsc clocksource as reliable */
-       set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+       /*
+        * TSC on Intel Atom SoCs is reliable and of known frequency.
+        * See tsc_msr.c for details.
+        */
+       setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+       setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
        return fast_calibrate;
 }
index 59253db41bbc900d238e361b9fce339161be1753..e0607c77a1bd67a06fe49f58c50c1bfe9af9da61 100644 (file)
@@ -78,8 +78,12 @@ static unsigned long __init tangier_calibrate_tsc(void)
        pr_debug("Setting lapic_timer_frequency = %d\n",
                        lapic_timer_frequency);
 
-       /* mark tsc clocksource as reliable */
-       set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
+       /*
+        * TSC on Intel Atom SoCs is reliable and of known frequency.
+        * See tsc_msr.c for details.
+        */
+       setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+       setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
        return fast_calibrate;
 }