TSC on Intel Atom SoCs capable of determining TSC frequency by MSR is
reliable and the frequency is known (because it's provided by HW).
On these platforms PIT/HPET is generally not available so
calibration won't work at all and also TSC is the only reliable
clocksource. So we set both X86_FEATURE_TSC_KNOWN_FREQ and
X86_FEATURE_TSC_RELIABLE flags to make sure the calibration is
skipped and no watchdog on TSC.

Signed-off-by: Bin Gao <bin....@intel.com>
---
 arch/x86/kernel/tsc_msr.c           | 18 ++++++++++++++++++
 arch/x86/platform/intel-mid/mfld.c  |  9 +++++++--
 arch/x86/platform/intel-mid/mrfld.c |  8 ++++++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..c0f137c 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,23 @@ 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 a HW way to report 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 marke TSC reliable to avoid watchdog on it.
+        */
+       setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
        return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..e793fe5 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -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;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..e0607c7 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -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;
 }
-- 
1.9.1

Reply via email to