All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/10] x86/tsc: fast calibration updates
@ 2016-06-17  5:22 Len Brown
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
  2016-06-17  7:36 ` [PATCH 0/10] x86/tsc: fast calibration updates Thomas Gleixner
  0 siblings, 2 replies; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel

Originally I wrote this series to increase TSC calibration
accuracy and speed, but it now it also includes
changes that are mandatory for some systems to work correctly.
In particular, the Airmont table entires are already being
used in products, and some BXT steppings will fail without
the check added by patch 10.

LKP tested this patch series in early April on top of 4.6-rc1
and found a failure.  That failure has been fixed
upstream in 4.6 by commit 886123fb3a86
(x86/tsc: Read all ratio bits from MSR_PLATFORM_INFO)

So I have re-based the series on top of 4.7-rc3
to take advantage of that fix, as well as to handle
3 merge conflicts due to intervening upstream commits.

The series now starts by reverting e2724e9d9692
(x86/tsc: Add missing Cherrytrail frequency to the table)
as that is replaced by the more correct and complete
"x86 tsc_msr: Add Airmont reference clock values" in this series.

Also, syntax changes were necessary to both
"x86 tsc: enumerate SKL cpu_khz and tsc_khz via CPUID"
"x86 tsc: enumerate BXT tsc_khz via CPUID"
in response to cleanups recently applied upstream to tsc.c

[PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to
[PATCH 02/10] x86 tsc_msr: Identify Intel-specific code
[PATCH 03/10] x86 tsc_msr: Remove debugging messages
[PATCH 04/10] x86 tsc_msr: Update comments, expand definitions
[PATCH 05/10] x86 tsc_msr: Correct Silvermont reference clock values
[PATCH 06/10] x86 tsc_msr: Add Airmont reference clock values
[PATCH 07/10] x86 tsc_msr: Extend to include Intel Core Architecture
[PATCH 08/10] x86 tsc_msr: Remove irqoff around MSR-based TSC
[PATCH 09/10] x86 tsc: enumerate SKL cpu_khz and tsc_khz via CPUID
[PATCH 10/10] x86 tsc: enumerate BXT tsc_khz via CPUID

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table"
  2016-06-17  5:22 [PATCH 0/10] x86/tsc: fast calibration updates Len Brown
@ 2016-06-17  5:22 ` Len Brown
  2016-06-17  5:22   ` [PATCH 02/10] x86 tsc_msr: Identify Intel-specific code Len Brown
                     ` (9 more replies)
  2016-06-17  7:36 ` [PATCH 0/10] x86/tsc: fast calibration updates Thomas Gleixner
  1 sibling, 10 replies; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

This reverts commit e2724e9d969294879936daf7833d4adda26c8efc.

as it is incomplete, and is replaced by a more complete
pach later in this series.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/tsc_msr.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 9911a06..6aa0f4d 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -23,7 +23,6 @@
 #include <asm/param.h>
 
 /* CPU reference clock frequency: in KHz */
-#define FREQ_80		80000
 #define FREQ_83		83200
 #define FREQ_100	99840
 #define FREQ_133	133200
@@ -57,8 +56,6 @@ static struct freq_desc freq_desc_tables[] = {
 	{ 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } },
 	/* ANN */
 	{ 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } },
-	/* AIRMONT */
-	{ 6, 0x4c, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, FREQ_80,	0, 0, 0 } },
 };
 
 static int match_cpu(u8 family, u8 model)
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 02/10] x86 tsc_msr: Identify Intel-specific code
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:10     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
  2016-06-17  5:22   ` [PATCH 03/10] x86 tsc_msr: Remove debugging messages Len Brown
                     ` (8 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

try_msr_calibrate_tsc() is currently Intel-specific,
and should not execute on any other vendor's parts.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/tsc_msr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 6aa0f4d..4ec5e56 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -86,6 +86,9 @@ unsigned long try_msr_calibrate_tsc(void)
 	unsigned long res;
 	int cpu_index;
 
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
 	cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model);
 	if (cpu_index < 0)
 		return 0;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 03/10] x86 tsc_msr: Remove debugging messages
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
  2016-06-17  5:22   ` [PATCH 02/10] x86 tsc_msr: Identify Intel-specific code Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:10     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
  2016-06-17  5:22   ` [PATCH 04/10] x86 tsc_msr: Update comments, expand definitions Len Brown
                     ` (7 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

Debugging messages are not necessary after all of the
possible hardware failures that never occur.
Instead, this code can simply return 0.

This code also doesn't need to print in the success case.
tsc_init() already prints the TSC frequency,
and apic=debug is available if anybody really is
interested in printing the LAPIC frequency.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/tsc_msr.c | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 4ec5e56..f7ba44b 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -76,9 +76,10 @@ static int match_cpu(u8 family, u8 model)
 	(freq_desc_tables[cpu_index].freqs[freq_id])
 
 /*
- * Do MSR calibration only for known/supported CPUs.
+ * MSR-based CPU/TSC frequency discovery for certain CPUs.
  *
- * Returns the calibration value or 0 if MSR calibration failed.
+ * Set global "lapic_timer_frequency" to bus_clock_cycles/jiffy
+ * Return processor base frequency in KHz, or 0 on failure.
  */
 unsigned long try_msr_calibrate_tsc(void)
 {
@@ -100,31 +101,17 @@ unsigned long try_msr_calibrate_tsc(void)
 		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
 		ratio = (hi >> 8) & 0x1f;
 	}
-	pr_info("Maximum core-clock to bus-clock ratio: 0x%x\n", ratio);
-
-	if (!ratio)
-		goto fail;
 
 	/* Get FSB FREQ ID */
 	rdmsr(MSR_FSB_FREQ, lo, hi);
 	freq_id = lo & 0x7;
 	freq = id_to_freq(cpu_index, freq_id);
-	pr_info("Resolved frequency ID: %u, frequency: %u KHz\n",
-				freq_id, freq);
-	if (!freq)
-		goto fail;
 
 	/* TSC frequency = maximum resolved freq * maximum resolved bus ratio */
 	res = freq * ratio;
-	pr_info("TSC runs at %lu KHz\n", res);
 
 #ifdef CONFIG_X86_LOCAL_APIC
 	lapic_timer_frequency = (freq * 1000) / HZ;
-	pr_info("lapic_timer_frequency = %d\n", lapic_timer_frequency);
 #endif
 	return res;
-
-fail:
-	pr_warn("Fast TSC calibration using MSR failed\n");
-	return 0;
 }
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 04/10] x86 tsc_msr: Update comments, expand definitions
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
  2016-06-17  5:22   ` [PATCH 02/10] x86 tsc_msr: Identify Intel-specific code Len Brown
  2016-06-17  5:22   ` [PATCH 03/10] x86 tsc_msr: Remove debugging messages Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:11     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
  2016-06-17  5:22   ` [PATCH 05/10] x86 tsc_msr: Correct Silvermont reference clock values Len Brown
                     ` (6 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

Syntax only, no functional change.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/tsc_msr.c | 36 ++++++++++--------------------------
 1 file changed, 10 insertions(+), 26 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index f7ba44b..4110f72 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -1,14 +1,5 @@
 /*
- * tsc_msr.c - MSR based TSC calibration on Intel Atom SoC platforms.
- *
- * TSC in Intel Atom SoC runs at a constant rate which can be figured
- * by this formula:
- * <maximum core-clock to bus-clock ratio> * <maximum resolved frequency>
- * See Intel 64 and IA-32 System Programming Guid section 16.12 and 30.11.5
- * for details.
- * Especially some Intel Atom SoCs don't have PIT(i8254) or HPET, so MSR
- * based calibration is the only option.
- *
+ * tsc_msr.c - TSC frequency enumeration via MSR
  *
  * Copyright (C) 2013 Intel Corporation
  * Author: Bin Gao <bin.gao@intel.com>
@@ -22,17 +13,10 @@
 #include <asm/apic.h>
 #include <asm/param.h>
 
-/* CPU reference clock frequency: in KHz */
-#define FREQ_83		83200
-#define FREQ_100	99840
-#define FREQ_133	133200
-#define FREQ_166	166400
-
 #define MAX_NUM_FREQS	8
 
 /*
- * According to Intel 64 and IA-32 System Programming Guide,
- * if MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be
+ * If MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be
  * read in MSR_PLATFORM_ID[12:8], otherwise in MSR_PERF_STAT[44:40].
  * Unfortunately some Intel Atom SoCs aren't quite compliant to this,
  * so we need manually differentiate SoC families. This is what the
@@ -47,15 +31,15 @@ struct freq_desc {
 
 static struct freq_desc freq_desc_tables[] = {
 	/* PNW */
-	{ 6, 0x27, 0, { 0, 0, 0, 0, 0, FREQ_100, 0, FREQ_83 } },
+	{ 6, 0x27, 0, { 0, 0, 0, 0, 0, 99840, 0, 83200 } },
 	/* CLV+ */
-	{ 6, 0x35, 0, { 0, FREQ_133, 0, 0, 0, FREQ_100, 0, FREQ_83 } },
-	/* TNG */
-	{ 6, 0x4a, 1, { 0, FREQ_100, FREQ_133, 0, 0, 0, 0, 0 } },
-	/* VLV2 */
-	{ 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } },
-	/* ANN */
-	{ 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } },
+	{ 6, 0x35, 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200 } },
+	/* TNG - Intel Atom processor Z3400 series */
+	{ 6, 0x4a, 1, { 0, 99840, 133200, 0, 0, 0, 0, 0 } },
+	/* VLV2 - Intel Atom processor E3000, Z3600, Z3700 series */
+	{ 6, 0x37, 1, { 83200, 99840, 133200, 166400, 0, 0, 0, 0 } },
+	/* ANN - Intel Atom processor Z3500 series */
+	{ 6, 0x5a, 1, { 83200, 99840, 133200, 99840, 0, 0, 0, 0 } },
 };
 
 static int match_cpu(u8 family, u8 model)
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 05/10] x86 tsc_msr: Correct Silvermont reference clock values
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
                     ` (2 preceding siblings ...)
  2016-06-17  5:22   ` [PATCH 04/10] x86 tsc_msr: Update comments, expand definitions Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:11     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
  2016-06-17  5:22   ` [PATCH 06/10] x86 tsc_msr: Add Airmont " Len Brown
                     ` (5 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

Atom processors use a 19.2 MHz crystal oscillator.

Early processors generate 100 MHz via 19.2 MHz * 26 / 5 = 99.84 MHz.

Later preocessor generate 100 MHz via 19.2 MHz * 125 / 24 = 100 MHz.

Update the Silvermont-based tables accordingly,
matching the Software Developers Manual.

Also, correct a 166 MHz entry that should have been 116 MHz,
and add a missing 80 MHz entry.

Reported-by: Stephane Gasparini <stephane.gasparini@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/tsc_msr.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 4110f72..20487e2 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -35,11 +35,11 @@ static struct freq_desc freq_desc_tables[] = {
 	/* CLV+ */
 	{ 6, 0x35, 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200 } },
 	/* TNG - Intel Atom processor Z3400 series */
-	{ 6, 0x4a, 1, { 0, 99840, 133200, 0, 0, 0, 0, 0 } },
+	{ 6, 0x4a, 1, { 0, 100000, 133300, 0, 0, 0, 0, 0 } },
 	/* VLV2 - Intel Atom processor E3000, Z3600, Z3700 series */
-	{ 6, 0x37, 1, { 83200, 99840, 133200, 166400, 0, 0, 0, 0 } },
+	{ 6, 0x37, 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 } },
 	/* ANN - Intel Atom processor Z3500 series */
-	{ 6, 0x5a, 1, { 83200, 99840, 133200, 99840, 0, 0, 0, 0 } },
+	{ 6, 0x5a, 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0 } },
 };
 
 static int match_cpu(u8 family, u8 model)
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 06/10] x86 tsc_msr: Add Airmont reference clock values
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
                     ` (3 preceding siblings ...)
  2016-06-17  5:22   ` [PATCH 05/10] x86 tsc_msr: Correct Silvermont reference clock values Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:12     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
  2016-06-17  5:22   ` [PATCH 07/10] x86 tsc_msr: Extend to include Intel Core Architecture Len Brown
                     ` (4 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

per the Intel 64 and IA-32 Architecture Software Developer's Manual...

Add the reference clock for Intel Atom Processors
Based on the Airmont Microarchitecture.

Reported-by: Stephane Gasparini <stephane.gasparini@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/tsc_msr.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 20487e2..65b3d8cb 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -13,7 +13,7 @@
 #include <asm/apic.h>
 #include <asm/param.h>
 
-#define MAX_NUM_FREQS	8
+#define MAX_NUM_FREQS	9
 
 /*
  * If MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be
@@ -40,6 +40,9 @@ static struct freq_desc freq_desc_tables[] = {
 	{ 6, 0x37, 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 } },
 	/* ANN - Intel Atom processor Z3500 series */
 	{ 6, 0x5a, 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0 } },
+	/* AMT - Intel Atom processor X7-Z8000 and X5-Z8000 series */
+	{ 6, 0x4c, 1, { 83300, 100000, 133300, 116700,
+			80000, 93300, 90000, 88900, 87500 } },
 };
 
 static int match_cpu(u8 family, u8 model)
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 07/10] x86 tsc_msr: Extend to include Intel Core Architecture
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
                     ` (4 preceding siblings ...)
  2016-06-17  5:22   ` [PATCH 06/10] x86 tsc_msr: Add Airmont " Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:12     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
  2016-06-17  5:22   ` [PATCH 08/10] x86 tsc_msr: Remove irqoff around MSR-based TSC enumeration Len Brown
                     ` (3 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

tsc_msr is used to quickly and reliably
enumerate the CPU/TSC frequencies at boot time
For the Intel Atom Architecture.

Extend tsc_msr to include recent Intel Core Architecture.

As this code discovers BCLK, it also sets lapic_timer_frequency,
which allows LAPIC timer calibration to be skipped,
though it is already skipped on systems with a TSC deadline timer.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/tsc_msr.c | 49 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 65b3d8cb..9d56ebd 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -77,23 +77,56 @@ unsigned long try_msr_calibrate_tsc(void)
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
 		return 0;
 
+	/*
+	 * 100 MHz BCLK Core Architecture -- before SKL.
+	 * De-rate 100Mhz by about 0.25% to account
+	 * for the average effect of spread-spectrum clocking.
+	 */
+	switch (boot_cpu_data.x86_model) {
+
+	case 0x2A:	/* SNB */
+	case 0x3A:	/* IVB */
+		freq = 99773;
+		goto get_ratio;
+	case 0x2D:	/* SNB Xeon */
+	case 0x3E:	/* IVB Xeon */
+		freq = 99760;
+		goto get_ratio;
+	case 0x3C:	/* HSW */
+	case 0x3F:	/* HSW */
+	case 0x45:	/* HSW */
+	case 0x46:	/* HSW */
+	case 0x3D:	/* BDW */
+	case 0x47:	/* BDW */
+	case 0x4F:	/* BDX */
+	case 0x56:	/* BDX-DE */
+		freq = 99769;
+		goto get_ratio;
+	}
+
+	/*
+	 * Atom Architecture
+	 */
 	cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model);
 	if (cpu_index < 0)
 		return 0;
 
-	if (freq_desc_tables[cpu_index].msr_plat) {
-		rdmsr(MSR_PLATFORM_INFO, lo, hi);
-		ratio = (lo >> 8) & 0xff;
-	} else {
-		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-		ratio = (hi >> 8) & 0x1f;
-	}
-
 	/* Get FSB FREQ ID */
 	rdmsr(MSR_FSB_FREQ, lo, hi);
 	freq_id = lo & 0x7;
 	freq = id_to_freq(cpu_index, freq_id);
 
+	if (!freq_desc_tables[cpu_index].msr_plat) {
+		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+		ratio = (hi >> 8) & 0x1f;
+		goto done;
+	}
+
+get_ratio:
+	rdmsr(MSR_PLATFORM_INFO, lo, hi);
+	ratio = (lo >> 8) & 0xff;
+
+done:
 	/* TSC frequency = maximum resolved freq * maximum resolved bus ratio */
 	res = freq * ratio;
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 08/10] x86 tsc_msr: Remove irqoff around MSR-based TSC enumeration
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
                     ` (5 preceding siblings ...)
  2016-06-17  5:22   ` [PATCH 07/10] x86 tsc_msr: Extend to include Intel Core Architecture Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:12     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
  2016-07-11 19:33     ` tip-bot for Len Brown
  2016-06-17  5:22   ` [PATCH 09/10] x86 tsc: enumerate SKL cpu_khz and tsc_khz via CPUID Len Brown
                     ` (2 subsequent siblings)
  9 siblings, 2 replies; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

Remove the irqoff/irqon around MSR-based TSC enumeration,
as it is not necessary.

Also rename: try_msr_calibrate_tsc() to cpu_khz_from_msr(),
as that better describes what the routine does.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/include/asm/tsc.h | 3 +--
 arch/x86/kernel/tsc.c      | 5 +----
 arch/x86/kernel/tsc_msr.c  | 2 +-
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index 7428697..db1f779 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -52,7 +52,6 @@ extern int notsc_setup(char *);
 extern void tsc_save_sched_clock_state(void);
 extern void tsc_restore_sched_clock_state(void);
 
-/* MSR based TSC calibration for Intel Atom SoC platforms */
-unsigned long try_msr_calibrate_tsc(void);
+unsigned long cpu_khz_from_msr(void);
 
 #endif /* _ASM_X86_TSC_H */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 38ba6de..35a3976 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -674,10 +674,7 @@ unsigned long native_calibrate_tsc(void)
 	unsigned long flags, latch, ms, fast_calibrate;
 	int hpet = is_hpet_enabled(), i, loopmin;
 
-	/* Calibrate TSC using MSR for Intel Atom SoCs */
-	local_irq_save(flags);
-	fast_calibrate = try_msr_calibrate_tsc();
-	local_irq_restore(flags);
+	fast_calibrate = cpu_khz_from_msr();
 	if (fast_calibrate)
 		return fast_calibrate;
 
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 9d56ebd..e0c2b30 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -68,7 +68,7 @@ static int match_cpu(u8 family, u8 model)
  * Set global "lapic_timer_frequency" to bus_clock_cycles/jiffy
  * Return processor base frequency in KHz, or 0 on failure.
  */
-unsigned long try_msr_calibrate_tsc(void)
+unsigned long cpu_khz_from_msr(void)
 {
 	u32 lo, hi, ratio, freq_id, freq;
 	unsigned long res;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 09/10] x86 tsc: enumerate SKL cpu_khz and tsc_khz via CPUID
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
                     ` (6 preceding siblings ...)
  2016-06-17  5:22   ` [PATCH 08/10] x86 tsc_msr: Remove irqoff around MSR-based TSC enumeration Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:13     ` [tip:x86/timers] x86/tsc: Enumerate " tip-bot for Len Brown
  2016-07-11 19:34     ` tip-bot for Len Brown
  2016-06-17  5:22   ` [PATCH 10/10] x86 tsc: enumerate BXT " Len Brown
  2016-07-10 18:09   ` [tip:x86/timers] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" tip-bot for Len Brown
  9 siblings, 2 replies; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown

From: Len Brown <len.brown@intel.com>

Skylake CPU base-frequency and TSC frequency may differ
by up to 2%.

Enumerate CPU and TSC frequencies separately, allowing
cpu_khz and tsc_khz to differ.

The existing CPU frequency calibration mechanism is unchanged.
However, CPUID extensions are preferred, when available.

CPUID.0x16 is preferred over MSR and timer calibration
for CPU frequency discovery.

CPUID.0x15 takes precedence over CPU-frequency
for TSC frequency discovery.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/include/asm/tsc.h      |  1 +
 arch/x86/include/asm/x86_init.h |  4 ++-
 arch/x86/kernel/tsc.c           | 75 +++++++++++++++++++++++++++++++++++++----
 arch/x86/kernel/x86_init.c      |  1 +
 4 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index db1f779..a30591e 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -36,6 +36,7 @@ extern void mark_tsc_unstable(char *reason);
 extern int unsynchronized_tsc(void);
 extern int check_tsc_unstable(void);
 extern int check_tsc_disabled(void);
+extern unsigned long native_calibrate_cpu(void);
 extern unsigned long native_calibrate_tsc(void);
 extern unsigned long long native_sched_clock_from_tsc(u64 tsc);
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 4dcdf74..08a08a8 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -181,7 +181,8 @@ struct x86_legacy_features {
 
 /**
  * struct x86_platform_ops - platform specific runtime functions
- * @calibrate_tsc:		calibrate TSC
+ * @calibrate_cpu:		calibrate CPU
+ * @calibrate_tsc:		calibrate TSC, if different from CPU
  * @get_wallclock:		get time from HW clock like RTC etc.
  * @set_wallclock:		set time back to HW clock
  * @is_untracked_pat_range	exclude from PAT logic
@@ -200,6 +201,7 @@ struct x86_legacy_features {
  * 				semantics.
  */
 struct x86_platform_ops {
+	unsigned long (*calibrate_cpu)(void);
 	unsigned long (*calibrate_tsc)(void);
 	void (*get_wallclock)(struct timespec *ts);
 	int (*set_wallclock)(const struct timespec *ts);
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 35a3976..e1496b7 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -239,7 +239,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
 	return ns;
 }
 
-static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
+static void set_cyc2ns_scale(unsigned long khz, int cpu)
 {
 	unsigned long long tsc_now, ns_now;
 	struct cyc2ns_data *data;
@@ -248,7 +248,7 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
 	local_irq_save(flags);
 	sched_clock_idle_sleep_event();
 
-	if (!cpu_khz)
+	if (!khz)
 		goto done;
 
 	data = cyc2ns_write_begin(cpu);
@@ -261,7 +261,7 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
 	 * time function is continuous; see the comment near struct
 	 * cyc2ns_data.
 	 */
-	clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, cpu_khz,
+	clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, khz,
 			       NSEC_PER_MSEC, 0);
 
 	/*
@@ -665,15 +665,72 @@ success:
 }
 
 /**
- * native_calibrate_tsc - calibrate the tsc on boot
+ * native_calibrate_tsc
+ * Determine TSC frequency via CPUID, else return 0.
  */
 unsigned long native_calibrate_tsc(void)
 {
+	unsigned int eax_denominator, ebx_numerator, ecx_hz, edx;
+	unsigned int crystal_khz;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
+	if (boot_cpu_data.cpuid_level < 0x15)
+		return 0;
+
+	eax_denominator = ebx_numerator = ecx_hz = edx = 0;
+
+	/* CPUID 15H TSC/Crystal ratio, plus optionally Crystal Hz */
+	cpuid(0x15, &eax_denominator, &ebx_numerator, &ecx_hz, &edx);
+
+	if (ebx_numerator == 0 || eax_denominator == 0)
+		return 0;
+
+	crystal_khz = ecx_hz / 1000;
+
+	if (crystal_khz == 0) {
+		switch (boot_cpu_data.x86_model) {
+		case 0x4E:	/* SKL */
+		case 0x5E:	/* SKL */
+			crystal_khz = 24000;	/* 24 MHz */
+		}
+	}
+
+	return crystal_khz * ebx_numerator / eax_denominator;
+}
+
+static unsigned long cpu_khz_from_cpuid(void)
+{
+	unsigned int eax_base_mhz, ebx_max_mhz, ecx_bus_mhz, edx;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
+	if (boot_cpu_data.cpuid_level < 0x16)
+		return 0;
+
+	eax_base_mhz = ebx_max_mhz = ecx_bus_mhz = edx = 0;
+
+	cpuid(0x16, &eax_base_mhz, &ebx_max_mhz, &ecx_bus_mhz, &edx);
+
+	return eax_base_mhz * 1000;
+}
+
+/**
+ * native_calibrate_cpu - calibrate the cpu on boot
+ */
+unsigned long native_calibrate_cpu(void)
+{
 	u64 tsc1, tsc2, delta, ref1, ref2;
 	unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
 	unsigned long flags, latch, ms, fast_calibrate;
 	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;
@@ -834,8 +891,10 @@ int recalibrate_cpu_khz(void)
 	if (!boot_cpu_has(X86_FEATURE_TSC))
 		return -ENODEV;
 
+	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
-	cpu_khz = tsc_khz;
+	if (tsc_khz == 0)
+		tsc_khz = cpu_khz;
 	cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy,
 						    cpu_khz_old, cpu_khz);
 
@@ -1241,8 +1300,10 @@ void __init tsc_init(void)
 		return;
 	}
 
+	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
-	cpu_khz = tsc_khz;
+	if (tsc_khz == 0)
+		tsc_khz = cpu_khz;
 
 	if (!tsc_khz) {
 		mark_tsc_unstable("could not calculate TSC khz");
@@ -1262,7 +1323,7 @@ void __init tsc_init(void)
 	 */
 	for_each_possible_cpu(cpu) {
 		cyc2ns_init(cpu);
-		set_cyc2ns_scale(cpu_khz, cpu);
+		set_cyc2ns_scale(tsc_khz, cpu);
 	}
 
 	if (tsc_disabled > 0)
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index dad5fe9..58b4592 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -92,6 +92,7 @@ static void default_nmi_init(void) { };
 static int default_i8042_detect(void) { return 1; };
 
 struct x86_platform_ops x86_platform = {
+	.calibrate_cpu			= native_calibrate_cpu,
 	.calibrate_tsc			= native_calibrate_tsc,
 	.get_wallclock			= mach_get_cmos_time,
 	.set_wallclock			= mach_set_rtc_mmss,
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 10/10] x86 tsc: enumerate BXT tsc_khz via CPUID
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
                     ` (7 preceding siblings ...)
  2016-06-17  5:22   ` [PATCH 09/10] x86 tsc: enumerate SKL cpu_khz and tsc_khz via CPUID Len Brown
@ 2016-06-17  5:22   ` Len Brown
  2016-07-10 18:13     ` [tip:x86/timers] x86/tsc: Enumerate " tip-bot for Len Brown
  2016-07-11 19:34     ` tip-bot for Len Brown
  2016-07-10 18:09   ` [tip:x86/timers] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" tip-bot for Len Brown
  9 siblings, 2 replies; 25+ messages in thread
From: Len Brown @ 2016-06-17  5:22 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Len Brown, Bin Gao

From: Len Brown <len.brown@intel.com>

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.

Signed-off-by: Bin Gao <bin.gao@intel.com>
[lenb: simplified]
Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/tsc.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index e1496b7..2a952fc 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -693,7 +693,11 @@ unsigned long native_calibrate_tsc(void)
 		switch (boot_cpu_data.x86_model) {
 		case 0x4E:	/* SKL */
 		case 0x5E:	/* SKL */
-			crystal_khz = 24000;	/* 24 MHz */
+			crystal_khz = 24000;	/* 24.0 MHz */
+			break;
+		case 0x5C:	/* BXT */
+			crystal_khz = 19200;	/* 19.2 MHz */
+			break;
 		}
 	}
 
@@ -895,6 +899,8 @@ int recalibrate_cpu_khz(void)
 	tsc_khz = x86_platform.calibrate_tsc();
 	if (tsc_khz == 0)
 		tsc_khz = cpu_khz;
+	else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz)
+		cpu_khz = tsc_khz;
 	cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy,
 						    cpu_khz_old, cpu_khz);
 
@@ -1302,8 +1308,16 @@ void __init tsc_init(void)
 
 	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
+
+	/*
+	 * Trust non-zero tsc_khz as authorative,
+	 * and use it to sanity check cpu_khz,
+	 * which will be off if system timer is off.
+	 */
 	if (tsc_khz == 0)
 		tsc_khz = cpu_khz;
+	else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz)
+		cpu_khz = tsc_khz;
 
 	if (!tsc_khz) {
 		mark_tsc_unstable("could not calculate TSC khz");
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/10] x86/tsc: fast calibration updates
  2016-06-17  5:22 [PATCH 0/10] x86/tsc: fast calibration updates Len Brown
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
@ 2016-06-17  7:36 ` Thomas Gleixner
  1 sibling, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2016-06-17  7:36 UTC (permalink / raw)
  To: Len Brown; +Cc: x86, linux-kernel

On Fri, 17 Jun 2016, Len Brown wrote:

> Originally I wrote this series to increase TSC calibration
> accuracy and speed, but it now it also includes
> changes that are mandatory for some systems to work correctly.
> In particular, the Airmont table entires are already being
> used in products, and some BXT steppings will fail without
> the check added by patch 10.
> 
> LKP tested this patch series in early April on top of 4.6-rc1
> and found a failure.  That failure has been fixed
> upstream in 4.6 by commit 886123fb3a86
> (x86/tsc: Read all ratio bits from MSR_PLATFORM_INFO)
> 
> So I have re-based the series on top of 4.7-rc3
> to take advantage of that fix, as well as to handle
> 3 merge conflicts due to intervening upstream commits.

Very nice work and good structured patches!

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [tip:x86/timers] Revert "x86/tsc: Add missing Cherrytrail frequency to the table"
  2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
                     ` (8 preceding siblings ...)
  2016-06-17  5:22   ` [PATCH 10/10] x86 tsc: enumerate BXT " Len Brown
@ 2016-07-10 18:09   ` tip-bot for Len Brown
  9 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, peterz, len.brown, torvalds, mingo, linux-kernel, tglx

Commit-ID:  fc5f3ac24720012909c224a63ca3217f4759967d
Gitweb:     http://git.kernel.org/tip/fc5f3ac24720012909c224a63ca3217f4759967d
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:43 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:12 +0200

Revert "x86/tsc: Add missing Cherrytrail frequency to the table"

This reverts commit:

  e2724e9d9692 ("x86/tsc: Add missing Cherrytrail frequency to the table")

... as it is incomplete, and is replaced by a more complete patch
later in this series.

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/2199d0e959f7f71a18827268b5d060f8d3831639.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/tsc_msr.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 9911a06..6aa0f4d 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -23,7 +23,6 @@
 #include <asm/param.h>
 
 /* CPU reference clock frequency: in KHz */
-#define FREQ_80		80000
 #define FREQ_83		83200
 #define FREQ_100	99840
 #define FREQ_133	133200
@@ -57,8 +56,6 @@ static struct freq_desc freq_desc_tables[] = {
 	{ 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } },
 	/* ANN */
 	{ 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } },
-	/* AIRMONT */
-	{ 6, 0x4c, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, FREQ_80,	0, 0, 0 } },
 };
 
 static int match_cpu(u8 family, u8 model)

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc_msr: Identify Intel-specific code
  2016-06-17  5:22   ` [PATCH 02/10] x86 tsc_msr: Identify Intel-specific code Len Brown
@ 2016-07-10 18:10     ` tip-bot for Len Brown
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: torvalds, peterz, hpa, tglx, len.brown, linux-kernel, mingo

Commit-ID:  ba8268330dc18d309a39175ea4d2c5d86c2cef09
Gitweb:     http://git.kernel.org/tip/ba8268330dc18d309a39175ea4d2c5d86c2cef09
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:44 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:12 +0200

x86/tsc_msr: Identify Intel-specific code

try_msr_calibrate_tsc() is currently Intel-specific,
and should not execute on any other vendor's parts.

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/1fe23c052826bdcfeb3d45045aa02246078cb5a7.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/tsc_msr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 6aa0f4d..4ec5e56 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -86,6 +86,9 @@ unsigned long try_msr_calibrate_tsc(void)
 	unsigned long res;
 	int cpu_index;
 
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
 	cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model);
 	if (cpu_index < 0)
 		return 0;

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc_msr: Remove debugging messages
  2016-06-17  5:22   ` [PATCH 03/10] x86 tsc_msr: Remove debugging messages Len Brown
@ 2016-07-10 18:10     ` tip-bot for Len Brown
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: torvalds, len.brown, tglx, peterz, linux-kernel, mingo, hpa

Commit-ID:  14bb4e34860af48ef1ea0f52b11611ce4db987fe
Gitweb:     http://git.kernel.org/tip/14bb4e34860af48ef1ea0f52b11611ce4db987fe
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:45 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:13 +0200

x86/tsc_msr: Remove debugging messages

Debugging messages are not necessary after all of the
possible hardware failures that never occur.
Instead, this code can simply return 0.

This code also doesn't need to print in the success case.
tsc_init() already prints the TSC frequency,
and apic=debug is available if anybody really is
interested in printing the LAPIC frequency.

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/cf03279a125b95dfa9b8d3d5b4a66de09cd04050.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/tsc_msr.c | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 4ec5e56..f7ba44b 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -76,9 +76,10 @@ static int match_cpu(u8 family, u8 model)
 	(freq_desc_tables[cpu_index].freqs[freq_id])
 
 /*
- * Do MSR calibration only for known/supported CPUs.
+ * MSR-based CPU/TSC frequency discovery for certain CPUs.
  *
- * Returns the calibration value or 0 if MSR calibration failed.
+ * Set global "lapic_timer_frequency" to bus_clock_cycles/jiffy
+ * Return processor base frequency in KHz, or 0 on failure.
  */
 unsigned long try_msr_calibrate_tsc(void)
 {
@@ -100,31 +101,17 @@ unsigned long try_msr_calibrate_tsc(void)
 		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
 		ratio = (hi >> 8) & 0x1f;
 	}
-	pr_info("Maximum core-clock to bus-clock ratio: 0x%x\n", ratio);
-
-	if (!ratio)
-		goto fail;
 
 	/* Get FSB FREQ ID */
 	rdmsr(MSR_FSB_FREQ, lo, hi);
 	freq_id = lo & 0x7;
 	freq = id_to_freq(cpu_index, freq_id);
-	pr_info("Resolved frequency ID: %u, frequency: %u KHz\n",
-				freq_id, freq);
-	if (!freq)
-		goto fail;
 
 	/* TSC frequency = maximum resolved freq * maximum resolved bus ratio */
 	res = freq * ratio;
-	pr_info("TSC runs at %lu KHz\n", res);
 
 #ifdef CONFIG_X86_LOCAL_APIC
 	lapic_timer_frequency = (freq * 1000) / HZ;
-	pr_info("lapic_timer_frequency = %d\n", lapic_timer_frequency);
 #endif
 	return res;
-
-fail:
-	pr_warn("Fast TSC calibration using MSR failed\n");
-	return 0;
 }

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc_msr: Update comments, expand definitions
  2016-06-17  5:22   ` [PATCH 04/10] x86 tsc_msr: Update comments, expand definitions Len Brown
@ 2016-07-10 18:11     ` tip-bot for Len Brown
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:11 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, torvalds, peterz, tglx, len.brown, linux-kernel, hpa

Commit-ID:  9e0cae9f6227f946fb0076b6a68c88156137f618
Gitweb:     http://git.kernel.org/tip/9e0cae9f6227f946fb0076b6a68c88156137f618
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:46 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:13 +0200

x86/tsc_msr: Update comments, expand definitions

Syntax only, no functional change.

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/8653a2dba21fef122fc7b29eafb750e2004d3976.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/tsc_msr.c | 36 ++++++++++--------------------------
 1 file changed, 10 insertions(+), 26 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index f7ba44b..4110f72 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -1,14 +1,5 @@
 /*
- * tsc_msr.c - MSR based TSC calibration on Intel Atom SoC platforms.
- *
- * TSC in Intel Atom SoC runs at a constant rate which can be figured
- * by this formula:
- * <maximum core-clock to bus-clock ratio> * <maximum resolved frequency>
- * See Intel 64 and IA-32 System Programming Guid section 16.12 and 30.11.5
- * for details.
- * Especially some Intel Atom SoCs don't have PIT(i8254) or HPET, so MSR
- * based calibration is the only option.
- *
+ * tsc_msr.c - TSC frequency enumeration via MSR
  *
  * Copyright (C) 2013 Intel Corporation
  * Author: Bin Gao <bin.gao@intel.com>
@@ -22,17 +13,10 @@
 #include <asm/apic.h>
 #include <asm/param.h>
 
-/* CPU reference clock frequency: in KHz */
-#define FREQ_83		83200
-#define FREQ_100	99840
-#define FREQ_133	133200
-#define FREQ_166	166400
-
 #define MAX_NUM_FREQS	8
 
 /*
- * According to Intel 64 and IA-32 System Programming Guide,
- * if MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be
+ * If MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be
  * read in MSR_PLATFORM_ID[12:8], otherwise in MSR_PERF_STAT[44:40].
  * Unfortunately some Intel Atom SoCs aren't quite compliant to this,
  * so we need manually differentiate SoC families. This is what the
@@ -47,15 +31,15 @@ struct freq_desc {
 
 static struct freq_desc freq_desc_tables[] = {
 	/* PNW */
-	{ 6, 0x27, 0, { 0, 0, 0, 0, 0, FREQ_100, 0, FREQ_83 } },
+	{ 6, 0x27, 0, { 0, 0, 0, 0, 0, 99840, 0, 83200 } },
 	/* CLV+ */
-	{ 6, 0x35, 0, { 0, FREQ_133, 0, 0, 0, FREQ_100, 0, FREQ_83 } },
-	/* TNG */
-	{ 6, 0x4a, 1, { 0, FREQ_100, FREQ_133, 0, 0, 0, 0, 0 } },
-	/* VLV2 */
-	{ 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } },
-	/* ANN */
-	{ 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } },
+	{ 6, 0x35, 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200 } },
+	/* TNG - Intel Atom processor Z3400 series */
+	{ 6, 0x4a, 1, { 0, 99840, 133200, 0, 0, 0, 0, 0 } },
+	/* VLV2 - Intel Atom processor E3000, Z3600, Z3700 series */
+	{ 6, 0x37, 1, { 83200, 99840, 133200, 166400, 0, 0, 0, 0 } },
+	/* ANN - Intel Atom processor Z3500 series */
+	{ 6, 0x5a, 1, { 83200, 99840, 133200, 99840, 0, 0, 0, 0 } },
 };
 
 static int match_cpu(u8 family, u8 model)

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc_msr: Correct Silvermont reference clock values
  2016-06-17  5:22   ` [PATCH 05/10] x86 tsc_msr: Correct Silvermont reference clock values Len Brown
@ 2016-07-10 18:11     ` tip-bot for Len Brown
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:11 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, tglx, torvalds, len.brown, linux-kernel, peterz,
	stephane.gasparini, mingo

Commit-ID:  05680e7fa8a4e700e031a5e72cd8c18265f0031a
Gitweb:     http://git.kernel.org/tip/05680e7fa8a4e700e031a5e72cd8c18265f0031a
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:47 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:13 +0200

x86/tsc_msr: Correct Silvermont reference clock values

Atom processors use a 19.2 MHz crystal oscillator.

Early processors generate 100 MHz via 19.2 MHz * 26 / 5 = 99.84 MHz.

Later preocessor generate 100 MHz via 19.2 MHz * 125 / 24 = 100 MHz.

Update the Silvermont-based tables accordingly,
matching the Software Developers Manual.

Also, correct a 166 MHz entry that should have been 116 MHz,
and add a missing 80 MHz entry.

Reported-by: Stephane Gasparini <stephane.gasparini@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/5d7561655dfb066ff10801b423405bae4d1cfbe2.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/tsc_msr.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 4110f72..20487e2 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -35,11 +35,11 @@ static struct freq_desc freq_desc_tables[] = {
 	/* CLV+ */
 	{ 6, 0x35, 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200 } },
 	/* TNG - Intel Atom processor Z3400 series */
-	{ 6, 0x4a, 1, { 0, 99840, 133200, 0, 0, 0, 0, 0 } },
+	{ 6, 0x4a, 1, { 0, 100000, 133300, 0, 0, 0, 0, 0 } },
 	/* VLV2 - Intel Atom processor E3000, Z3600, Z3700 series */
-	{ 6, 0x37, 1, { 83200, 99840, 133200, 166400, 0, 0, 0, 0 } },
+	{ 6, 0x37, 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 } },
 	/* ANN - Intel Atom processor Z3500 series */
-	{ 6, 0x5a, 1, { 83200, 99840, 133200, 99840, 0, 0, 0, 0 } },
+	{ 6, 0x5a, 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0 } },
 };
 
 static int match_cpu(u8 family, u8 model)

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc_msr: Add Airmont reference clock values
  2016-06-17  5:22   ` [PATCH 06/10] x86 tsc_msr: Add Airmont " Len Brown
@ 2016-07-10 18:12     ` tip-bot for Len Brown
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:12 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, peterz, torvalds, tglx, stephane.gasparini, mingo,
	linux-kernel, len.brown

Commit-ID:  6fcb41cdaee5056c96de88ee095bddd27a7697de
Gitweb:     http://git.kernel.org/tip/6fcb41cdaee5056c96de88ee095bddd27a7697de
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:48 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:13 +0200

x86/tsc_msr: Add Airmont reference clock values

per the Intel 64 and IA-32 Architecture Software Developer's Manual...

Add the reference clock for Intel Atom Processors
Based on the Airmont Microarchitecture.

Reported-by: Stephane Gasparini <stephane.gasparini@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/abc6a0f4b18281410da1a3f26e2819d8e03e144f.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/tsc_msr.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 20487e2..65b3d8cb 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -13,7 +13,7 @@
 #include <asm/apic.h>
 #include <asm/param.h>
 
-#define MAX_NUM_FREQS	8
+#define MAX_NUM_FREQS	9
 
 /*
  * If MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be
@@ -40,6 +40,9 @@ static struct freq_desc freq_desc_tables[] = {
 	{ 6, 0x37, 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 } },
 	/* ANN - Intel Atom processor Z3500 series */
 	{ 6, 0x5a, 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0 } },
+	/* AMT - Intel Atom processor X7-Z8000 and X5-Z8000 series */
+	{ 6, 0x4c, 1, { 83300, 100000, 133300, 116700,
+			80000, 93300, 90000, 88900, 87500 } },
 };
 
 static int match_cpu(u8 family, u8 model)

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc_msr: Extend to include Intel Core Architecture
  2016-06-17  5:22   ` [PATCH 07/10] x86 tsc_msr: Extend to include Intel Core Architecture Len Brown
@ 2016-07-10 18:12     ` tip-bot for Len Brown
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:12 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, mingo, hpa, len.brown, torvalds, tglx, peterz

Commit-ID:  fc273eeef314cdaf0ac992b400d126f8184a4d1c
Gitweb:     http://git.kernel.org/tip/fc273eeef314cdaf0ac992b400d126f8184a4d1c
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:49 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:13 +0200

x86/tsc_msr: Extend to include Intel Core Architecture

tsc_msr is used to quickly and reliably
enumerate the CPU/TSC frequencies at boot time
For the Intel Atom Architecture.

Extend tsc_msr to include recent Intel Core Architecture.

As this code discovers BCLK, it also sets lapic_timer_frequency,
which allows LAPIC timer calibration to be skipped,
though it is already skipped on systems with a TSC deadline timer.

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/8c82d5a94b754b6015f8cf8ea1fde15821fc6611.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/tsc_msr.c | 49 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 65b3d8cb..9d56ebd 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -77,23 +77,56 @@ unsigned long try_msr_calibrate_tsc(void)
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
 		return 0;
 
+	/*
+	 * 100 MHz BCLK Core Architecture -- before SKL.
+	 * De-rate 100Mhz by about 0.25% to account
+	 * for the average effect of spread-spectrum clocking.
+	 */
+	switch (boot_cpu_data.x86_model) {
+
+	case 0x2A:	/* SNB */
+	case 0x3A:	/* IVB */
+		freq = 99773;
+		goto get_ratio;
+	case 0x2D:	/* SNB Xeon */
+	case 0x3E:	/* IVB Xeon */
+		freq = 99760;
+		goto get_ratio;
+	case 0x3C:	/* HSW */
+	case 0x3F:	/* HSW */
+	case 0x45:	/* HSW */
+	case 0x46:	/* HSW */
+	case 0x3D:	/* BDW */
+	case 0x47:	/* BDW */
+	case 0x4F:	/* BDX */
+	case 0x56:	/* BDX-DE */
+		freq = 99769;
+		goto get_ratio;
+	}
+
+	/*
+	 * Atom Architecture
+	 */
 	cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model);
 	if (cpu_index < 0)
 		return 0;
 
-	if (freq_desc_tables[cpu_index].msr_plat) {
-		rdmsr(MSR_PLATFORM_INFO, lo, hi);
-		ratio = (lo >> 8) & 0xff;
-	} else {
-		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-		ratio = (hi >> 8) & 0x1f;
-	}
-
 	/* Get FSB FREQ ID */
 	rdmsr(MSR_FSB_FREQ, lo, hi);
 	freq_id = lo & 0x7;
 	freq = id_to_freq(cpu_index, freq_id);
 
+	if (!freq_desc_tables[cpu_index].msr_plat) {
+		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+		ratio = (hi >> 8) & 0x1f;
+		goto done;
+	}
+
+get_ratio:
+	rdmsr(MSR_PLATFORM_INFO, lo, hi);
+	ratio = (lo >> 8) & 0xff;
+
+done:
 	/* TSC frequency = maximum resolved freq * maximum resolved bus ratio */
 	res = freq * ratio;
 

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc_msr: Remove irqoff around MSR-based TSC enumeration
  2016-06-17  5:22   ` [PATCH 08/10] x86 tsc_msr: Remove irqoff around MSR-based TSC enumeration Len Brown
@ 2016-07-10 18:12     ` tip-bot for Len Brown
  2016-07-11 19:33     ` tip-bot for Len Brown
  1 sibling, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:12 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: len.brown, tglx, torvalds, hpa, linux-kernel, mingo, peterz

Commit-ID:  5c3a67bbfa5cf936c71c7af4e2a3661813819684
Gitweb:     http://git.kernel.org/tip/5c3a67bbfa5cf936c71c7af4e2a3661813819684
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:50 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:14 +0200

x86/tsc_msr: Remove irqoff around MSR-based TSC enumeration

Remove the irqoff/irqon around MSR-based TSC enumeration,
as it is not necessary.

Also rename: try_msr_calibrate_tsc() to cpu_khz_from_msr(),
as that better describes what the routine does.

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/a6b5c3ecd3b068175d2309599ab28163fc34215e.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/tsc.h | 3 +--
 arch/x86/kernel/tsc.c      | 5 +----
 arch/x86/kernel/tsc_msr.c  | 2 +-
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index 7428697..db1f779 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -52,7 +52,6 @@ extern int notsc_setup(char *);
 extern void tsc_save_sched_clock_state(void);
 extern void tsc_restore_sched_clock_state(void);
 
-/* MSR based TSC calibration for Intel Atom SoC platforms */
-unsigned long try_msr_calibrate_tsc(void);
+unsigned long cpu_khz_from_msr(void);
 
 #endif /* _ASM_X86_TSC_H */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 38ba6de..35a3976 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -674,10 +674,7 @@ unsigned long native_calibrate_tsc(void)
 	unsigned long flags, latch, ms, fast_calibrate;
 	int hpet = is_hpet_enabled(), i, loopmin;
 
-	/* Calibrate TSC using MSR for Intel Atom SoCs */
-	local_irq_save(flags);
-	fast_calibrate = try_msr_calibrate_tsc();
-	local_irq_restore(flags);
+	fast_calibrate = cpu_khz_from_msr();
 	if (fast_calibrate)
 		return fast_calibrate;
 
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 9d56ebd..e0c2b30 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -68,7 +68,7 @@ static int match_cpu(u8 family, u8 model)
  * Set global "lapic_timer_frequency" to bus_clock_cycles/jiffy
  * Return processor base frequency in KHz, or 0 on failure.
  */
-unsigned long try_msr_calibrate_tsc(void)
+unsigned long cpu_khz_from_msr(void)
 {
 	u32 lo, hi, ratio, freq_id, freq;
 	unsigned long res;

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc: Enumerate SKL cpu_khz and tsc_khz via CPUID
  2016-06-17  5:22   ` [PATCH 09/10] x86 tsc: enumerate SKL cpu_khz and tsc_khz via CPUID Len Brown
@ 2016-07-10 18:13     ` tip-bot for Len Brown
  2016-07-11 19:34     ` tip-bot for Len Brown
  1 sibling, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, len.brown, tglx, torvalds, peterz, mingo, hpa

Commit-ID:  1bf8915ae5156dff439d2c65314bd8fdde1b83bf
Gitweb:     http://git.kernel.org/tip/1bf8915ae5156dff439d2c65314bd8fdde1b83bf
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:51 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:14 +0200

x86/tsc: Enumerate SKL cpu_khz and tsc_khz via CPUID

Skylake CPU base-frequency and TSC frequency may differ
by up to 2%.

Enumerate CPU and TSC frequencies separately, allowing
cpu_khz and tsc_khz to differ.

The existing CPU frequency calibration mechanism is unchanged.
However, CPUID extensions are preferred, when available.

CPUID.0x16 is preferred over MSR and timer calibration
for CPU frequency discovery.

CPUID.0x15 takes precedence over CPU-frequency
for TSC frequency discovery.

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/b27ec289fd005833b27d694d9c2dbb716c5cdff7.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/tsc.h      |  1 +
 arch/x86/include/asm/x86_init.h |  4 ++-
 arch/x86/kernel/tsc.c           | 75 +++++++++++++++++++++++++++++++++++++----
 arch/x86/kernel/x86_init.c      |  1 +
 4 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index db1f779..a30591e 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -36,6 +36,7 @@ extern void mark_tsc_unstable(char *reason);
 extern int unsynchronized_tsc(void);
 extern int check_tsc_unstable(void);
 extern int check_tsc_disabled(void);
+extern unsigned long native_calibrate_cpu(void);
 extern unsigned long native_calibrate_tsc(void);
 extern unsigned long long native_sched_clock_from_tsc(u64 tsc);
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 4dcdf74..08a08a8 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -181,7 +181,8 @@ struct x86_legacy_features {
 
 /**
  * struct x86_platform_ops - platform specific runtime functions
- * @calibrate_tsc:		calibrate TSC
+ * @calibrate_cpu:		calibrate CPU
+ * @calibrate_tsc:		calibrate TSC, if different from CPU
  * @get_wallclock:		get time from HW clock like RTC etc.
  * @set_wallclock:		set time back to HW clock
  * @is_untracked_pat_range	exclude from PAT logic
@@ -200,6 +201,7 @@ struct x86_legacy_features {
  * 				semantics.
  */
 struct x86_platform_ops {
+	unsigned long (*calibrate_cpu)(void);
 	unsigned long (*calibrate_tsc)(void);
 	void (*get_wallclock)(struct timespec *ts);
 	int (*set_wallclock)(const struct timespec *ts);
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 35a3976..e1496b7 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -239,7 +239,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
 	return ns;
 }
 
-static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
+static void set_cyc2ns_scale(unsigned long khz, int cpu)
 {
 	unsigned long long tsc_now, ns_now;
 	struct cyc2ns_data *data;
@@ -248,7 +248,7 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
 	local_irq_save(flags);
 	sched_clock_idle_sleep_event();
 
-	if (!cpu_khz)
+	if (!khz)
 		goto done;
 
 	data = cyc2ns_write_begin(cpu);
@@ -261,7 +261,7 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
 	 * time function is continuous; see the comment near struct
 	 * cyc2ns_data.
 	 */
-	clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, cpu_khz,
+	clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, khz,
 			       NSEC_PER_MSEC, 0);
 
 	/*
@@ -665,15 +665,72 @@ success:
 }
 
 /**
- * native_calibrate_tsc - calibrate the tsc on boot
+ * native_calibrate_tsc
+ * Determine TSC frequency via CPUID, else return 0.
  */
 unsigned long native_calibrate_tsc(void)
 {
+	unsigned int eax_denominator, ebx_numerator, ecx_hz, edx;
+	unsigned int crystal_khz;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
+	if (boot_cpu_data.cpuid_level < 0x15)
+		return 0;
+
+	eax_denominator = ebx_numerator = ecx_hz = edx = 0;
+
+	/* CPUID 15H TSC/Crystal ratio, plus optionally Crystal Hz */
+	cpuid(0x15, &eax_denominator, &ebx_numerator, &ecx_hz, &edx);
+
+	if (ebx_numerator == 0 || eax_denominator == 0)
+		return 0;
+
+	crystal_khz = ecx_hz / 1000;
+
+	if (crystal_khz == 0) {
+		switch (boot_cpu_data.x86_model) {
+		case 0x4E:	/* SKL */
+		case 0x5E:	/* SKL */
+			crystal_khz = 24000;	/* 24 MHz */
+		}
+	}
+
+	return crystal_khz * ebx_numerator / eax_denominator;
+}
+
+static unsigned long cpu_khz_from_cpuid(void)
+{
+	unsigned int eax_base_mhz, ebx_max_mhz, ecx_bus_mhz, edx;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
+	if (boot_cpu_data.cpuid_level < 0x16)
+		return 0;
+
+	eax_base_mhz = ebx_max_mhz = ecx_bus_mhz = edx = 0;
+
+	cpuid(0x16, &eax_base_mhz, &ebx_max_mhz, &ecx_bus_mhz, &edx);
+
+	return eax_base_mhz * 1000;
+}
+
+/**
+ * native_calibrate_cpu - calibrate the cpu on boot
+ */
+unsigned long native_calibrate_cpu(void)
+{
 	u64 tsc1, tsc2, delta, ref1, ref2;
 	unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
 	unsigned long flags, latch, ms, fast_calibrate;
 	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;
@@ -834,8 +891,10 @@ int recalibrate_cpu_khz(void)
 	if (!boot_cpu_has(X86_FEATURE_TSC))
 		return -ENODEV;
 
+	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
-	cpu_khz = tsc_khz;
+	if (tsc_khz == 0)
+		tsc_khz = cpu_khz;
 	cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy,
 						    cpu_khz_old, cpu_khz);
 
@@ -1241,8 +1300,10 @@ void __init tsc_init(void)
 		return;
 	}
 
+	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
-	cpu_khz = tsc_khz;
+	if (tsc_khz == 0)
+		tsc_khz = cpu_khz;
 
 	if (!tsc_khz) {
 		mark_tsc_unstable("could not calculate TSC khz");
@@ -1262,7 +1323,7 @@ void __init tsc_init(void)
 	 */
 	for_each_possible_cpu(cpu) {
 		cyc2ns_init(cpu);
-		set_cyc2ns_scale(cpu_khz, cpu);
+		set_cyc2ns_scale(tsc_khz, cpu);
 	}
 
 	if (tsc_disabled > 0)
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index dad5fe9..58b4592 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -92,6 +92,7 @@ static void default_nmi_init(void) { };
 static int default_i8042_detect(void) { return 1; };
 
 struct x86_platform_ops x86_platform = {
+	.calibrate_cpu			= native_calibrate_cpu,
 	.calibrate_tsc			= native_calibrate_tsc,
 	.get_wallclock			= mach_get_cmos_time,
 	.set_wallclock			= mach_set_rtc_mmss,

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc: Enumerate BXT tsc_khz via CPUID
  2016-06-17  5:22   ` [PATCH 10/10] x86 tsc: enumerate BXT " Len Brown
@ 2016-07-10 18:13     ` tip-bot for Len Brown
  2016-07-11 19:34     ` tip-bot for Len Brown
  1 sibling, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-10 18:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, tglx, hpa, peterz, len.brown, linux-kernel, torvalds

Commit-ID:  a3dc6a4c9c329bf6ac4ee996c67557664d6b780e
Gitweb:     http://git.kernel.org/tip/a3dc6a4c9c329bf6ac4ee996c67557664d6b780e
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:52 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 10 Jul 2016 17:00:14 +0200

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>
---
 arch/x86/kernel/tsc.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index e1496b7..2a952fc 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -693,7 +693,11 @@ unsigned long native_calibrate_tsc(void)
 		switch (boot_cpu_data.x86_model) {
 		case 0x4E:	/* SKL */
 		case 0x5E:	/* SKL */
-			crystal_khz = 24000;	/* 24 MHz */
+			crystal_khz = 24000;	/* 24.0 MHz */
+			break;
+		case 0x5C:	/* BXT */
+			crystal_khz = 19200;	/* 19.2 MHz */
+			break;
 		}
 	}
 
@@ -895,6 +899,8 @@ int recalibrate_cpu_khz(void)
 	tsc_khz = x86_platform.calibrate_tsc();
 	if (tsc_khz == 0)
 		tsc_khz = cpu_khz;
+	else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz)
+		cpu_khz = tsc_khz;
 	cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy,
 						    cpu_khz_old, cpu_khz);
 
@@ -1302,8 +1308,16 @@ void __init tsc_init(void)
 
 	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
+
+	/*
+	 * Trust non-zero tsc_khz as authorative,
+	 * and use it to sanity check cpu_khz,
+	 * which will be off if system timer is off.
+	 */
 	if (tsc_khz == 0)
 		tsc_khz = cpu_khz;
+	else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz)
+		cpu_khz = tsc_khz;
 
 	if (!tsc_khz) {
 		mark_tsc_unstable("could not calculate TSC khz");

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc_msr: Remove irqoff around MSR-based TSC enumeration
  2016-06-17  5:22   ` [PATCH 08/10] x86 tsc_msr: Remove irqoff around MSR-based TSC enumeration Len Brown
  2016-07-10 18:12     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
@ 2016-07-11 19:33     ` tip-bot for Len Brown
  1 sibling, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-11 19:33 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, tglx, len.brown, torvalds, mingo, hpa, linux-kernel

Commit-ID:  02c0cd2dcf7fdc47d054b855b148ea8b82dbb7eb
Gitweb:     http://git.kernel.org/tip/02c0cd2dcf7fdc47d054b855b148ea8b82dbb7eb
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:50 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 11 Jul 2016 21:30:12 +0200

x86/tsc_msr: Remove irqoff around MSR-based TSC enumeration

Remove the irqoff/irqon around MSR-based TSC enumeration,
as it is not necessary.

Also rename: try_msr_calibrate_tsc() to cpu_khz_from_msr(),
as that better describes what the routine does.

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/a6b5c3ecd3b068175d2309599ab28163fc34215e.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/tsc.h | 3 +--
 arch/x86/kernel/tsc.c      | 5 +----
 arch/x86/kernel/tsc_msr.c  | 2 +-
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index 7428697..db1f779 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -52,7 +52,6 @@ extern int notsc_setup(char *);
 extern void tsc_save_sched_clock_state(void);
 extern void tsc_restore_sched_clock_state(void);
 
-/* MSR based TSC calibration for Intel Atom SoC platforms */
-unsigned long try_msr_calibrate_tsc(void);
+unsigned long cpu_khz_from_msr(void);
 
 #endif /* _ASM_X86_TSC_H */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 38ba6de..35a3976 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -674,10 +674,7 @@ unsigned long native_calibrate_tsc(void)
 	unsigned long flags, latch, ms, fast_calibrate;
 	int hpet = is_hpet_enabled(), i, loopmin;
 
-	/* Calibrate TSC using MSR for Intel Atom SoCs */
-	local_irq_save(flags);
-	fast_calibrate = try_msr_calibrate_tsc();
-	local_irq_restore(flags);
+	fast_calibrate = cpu_khz_from_msr();
 	if (fast_calibrate)
 		return fast_calibrate;
 
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 65b3d8cb..0fe720d 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -68,7 +68,7 @@ static int match_cpu(u8 family, u8 model)
  * Set global "lapic_timer_frequency" to bus_clock_cycles/jiffy
  * Return processor base frequency in KHz, or 0 on failure.
  */
-unsigned long try_msr_calibrate_tsc(void)
+unsigned long cpu_khz_from_msr(void)
 {
 	u32 lo, hi, ratio, freq_id, freq;
 	unsigned long res;

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc: Enumerate SKL cpu_khz and tsc_khz via CPUID
  2016-06-17  5:22   ` [PATCH 09/10] x86 tsc: enumerate SKL cpu_khz and tsc_khz via CPUID Len Brown
  2016-07-10 18:13     ` [tip:x86/timers] x86/tsc: Enumerate " tip-bot for Len Brown
@ 2016-07-11 19:34     ` tip-bot for Len Brown
  1 sibling, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-11 19:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, len.brown, peterz, linux-kernel, torvalds, mingo, hpa

Commit-ID:  aa297292d708e89773b3b2cdcaf33f01bfa095d8
Gitweb:     http://git.kernel.org/tip/aa297292d708e89773b3b2cdcaf33f01bfa095d8
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:51 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 11 Jul 2016 21:30:13 +0200

x86/tsc: Enumerate SKL cpu_khz and tsc_khz via CPUID

Skylake CPU base-frequency and TSC frequency may differ
by up to 2%.

Enumerate CPU and TSC frequencies separately, allowing
cpu_khz and tsc_khz to differ.

The existing CPU frequency calibration mechanism is unchanged.
However, CPUID extensions are preferred, when available.

CPUID.0x16 is preferred over MSR and timer calibration
for CPU frequency discovery.

CPUID.0x15 takes precedence over CPU-frequency
for TSC frequency discovery.

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/b27ec289fd005833b27d694d9c2dbb716c5cdff7.1466138954.git.len.brown@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/tsc.h      |  1 +
 arch/x86/include/asm/x86_init.h |  4 ++-
 arch/x86/kernel/tsc.c           | 75 +++++++++++++++++++++++++++++++++++++----
 arch/x86/kernel/x86_init.c      |  1 +
 4 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index db1f779..a30591e 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -36,6 +36,7 @@ extern void mark_tsc_unstable(char *reason);
 extern int unsynchronized_tsc(void);
 extern int check_tsc_unstable(void);
 extern int check_tsc_disabled(void);
+extern unsigned long native_calibrate_cpu(void);
 extern unsigned long native_calibrate_tsc(void);
 extern unsigned long long native_sched_clock_from_tsc(u64 tsc);
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 4dcdf74..08a08a8 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -181,7 +181,8 @@ struct x86_legacy_features {
 
 /**
  * struct x86_platform_ops - platform specific runtime functions
- * @calibrate_tsc:		calibrate TSC
+ * @calibrate_cpu:		calibrate CPU
+ * @calibrate_tsc:		calibrate TSC, if different from CPU
  * @get_wallclock:		get time from HW clock like RTC etc.
  * @set_wallclock:		set time back to HW clock
  * @is_untracked_pat_range	exclude from PAT logic
@@ -200,6 +201,7 @@ struct x86_legacy_features {
  * 				semantics.
  */
 struct x86_platform_ops {
+	unsigned long (*calibrate_cpu)(void);
 	unsigned long (*calibrate_tsc)(void);
 	void (*get_wallclock)(struct timespec *ts);
 	int (*set_wallclock)(const struct timespec *ts);
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 35a3976..e1496b7 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -239,7 +239,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
 	return ns;
 }
 
-static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
+static void set_cyc2ns_scale(unsigned long khz, int cpu)
 {
 	unsigned long long tsc_now, ns_now;
 	struct cyc2ns_data *data;
@@ -248,7 +248,7 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
 	local_irq_save(flags);
 	sched_clock_idle_sleep_event();
 
-	if (!cpu_khz)
+	if (!khz)
 		goto done;
 
 	data = cyc2ns_write_begin(cpu);
@@ -261,7 +261,7 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
 	 * time function is continuous; see the comment near struct
 	 * cyc2ns_data.
 	 */
-	clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, cpu_khz,
+	clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, khz,
 			       NSEC_PER_MSEC, 0);
 
 	/*
@@ -665,15 +665,72 @@ success:
 }
 
 /**
- * native_calibrate_tsc - calibrate the tsc on boot
+ * native_calibrate_tsc
+ * Determine TSC frequency via CPUID, else return 0.
  */
 unsigned long native_calibrate_tsc(void)
 {
+	unsigned int eax_denominator, ebx_numerator, ecx_hz, edx;
+	unsigned int crystal_khz;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
+	if (boot_cpu_data.cpuid_level < 0x15)
+		return 0;
+
+	eax_denominator = ebx_numerator = ecx_hz = edx = 0;
+
+	/* CPUID 15H TSC/Crystal ratio, plus optionally Crystal Hz */
+	cpuid(0x15, &eax_denominator, &ebx_numerator, &ecx_hz, &edx);
+
+	if (ebx_numerator == 0 || eax_denominator == 0)
+		return 0;
+
+	crystal_khz = ecx_hz / 1000;
+
+	if (crystal_khz == 0) {
+		switch (boot_cpu_data.x86_model) {
+		case 0x4E:	/* SKL */
+		case 0x5E:	/* SKL */
+			crystal_khz = 24000;	/* 24 MHz */
+		}
+	}
+
+	return crystal_khz * ebx_numerator / eax_denominator;
+}
+
+static unsigned long cpu_khz_from_cpuid(void)
+{
+	unsigned int eax_base_mhz, ebx_max_mhz, ecx_bus_mhz, edx;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+
+	if (boot_cpu_data.cpuid_level < 0x16)
+		return 0;
+
+	eax_base_mhz = ebx_max_mhz = ecx_bus_mhz = edx = 0;
+
+	cpuid(0x16, &eax_base_mhz, &ebx_max_mhz, &ecx_bus_mhz, &edx);
+
+	return eax_base_mhz * 1000;
+}
+
+/**
+ * native_calibrate_cpu - calibrate the cpu on boot
+ */
+unsigned long native_calibrate_cpu(void)
+{
 	u64 tsc1, tsc2, delta, ref1, ref2;
 	unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
 	unsigned long flags, latch, ms, fast_calibrate;
 	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;
@@ -834,8 +891,10 @@ int recalibrate_cpu_khz(void)
 	if (!boot_cpu_has(X86_FEATURE_TSC))
 		return -ENODEV;
 
+	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
-	cpu_khz = tsc_khz;
+	if (tsc_khz == 0)
+		tsc_khz = cpu_khz;
 	cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy,
 						    cpu_khz_old, cpu_khz);
 
@@ -1241,8 +1300,10 @@ void __init tsc_init(void)
 		return;
 	}
 
+	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
-	cpu_khz = tsc_khz;
+	if (tsc_khz == 0)
+		tsc_khz = cpu_khz;
 
 	if (!tsc_khz) {
 		mark_tsc_unstable("could not calculate TSC khz");
@@ -1262,7 +1323,7 @@ void __init tsc_init(void)
 	 */
 	for_each_possible_cpu(cpu) {
 		cyc2ns_init(cpu);
-		set_cyc2ns_scale(cpu_khz, cpu);
+		set_cyc2ns_scale(tsc_khz, cpu);
 	}
 
 	if (tsc_disabled > 0)
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index dad5fe9..58b4592 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -92,6 +92,7 @@ static void default_nmi_init(void) { };
 static int default_i8042_detect(void) { return 1; };
 
 struct x86_platform_ops x86_platform = {
+	.calibrate_cpu			= native_calibrate_cpu,
 	.calibrate_tsc			= native_calibrate_tsc,
 	.get_wallclock			= mach_get_cmos_time,
 	.set_wallclock			= mach_set_rtc_mmss,

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:x86/timers] x86/tsc: Enumerate BXT tsc_khz via CPUID
  2016-06-17  5:22   ` [PATCH 10/10] x86 tsc: enumerate BXT " Len Brown
  2016-07-10 18:13     ` [tip:x86/timers] x86/tsc: Enumerate " tip-bot for Len Brown
@ 2016-07-11 19:34     ` tip-bot for Len Brown
  1 sibling, 0 replies; 25+ messages in thread
From: tip-bot for Len Brown @ 2016-07-11 19:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, hpa, peterz, mingo, linux-kernel, len.brown, torvalds

Commit-ID:  ff4c86635ee12461fd3bd911d7d5253394da8f9d
Gitweb:     http://git.kernel.org/tip/ff4c86635ee12461fd3bd911d7d5253394da8f9d
Author:     Len Brown <len.brown@intel.com>
AuthorDate: Fri, 17 Jun 2016 01:22:52 -0400
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 11 Jul 2016 21:30:13 +0200

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>
---
 arch/x86/kernel/tsc.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index e1496b7..2a952fc 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -693,7 +693,11 @@ unsigned long native_calibrate_tsc(void)
 		switch (boot_cpu_data.x86_model) {
 		case 0x4E:	/* SKL */
 		case 0x5E:	/* SKL */
-			crystal_khz = 24000;	/* 24 MHz */
+			crystal_khz = 24000;	/* 24.0 MHz */
+			break;
+		case 0x5C:	/* BXT */
+			crystal_khz = 19200;	/* 19.2 MHz */
+			break;
 		}
 	}
 
@@ -895,6 +899,8 @@ int recalibrate_cpu_khz(void)
 	tsc_khz = x86_platform.calibrate_tsc();
 	if (tsc_khz == 0)
 		tsc_khz = cpu_khz;
+	else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz)
+		cpu_khz = tsc_khz;
 	cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy,
 						    cpu_khz_old, cpu_khz);
 
@@ -1302,8 +1308,16 @@ void __init tsc_init(void)
 
 	cpu_khz = x86_platform.calibrate_cpu();
 	tsc_khz = x86_platform.calibrate_tsc();
+
+	/*
+	 * Trust non-zero tsc_khz as authorative,
+	 * and use it to sanity check cpu_khz,
+	 * which will be off if system timer is off.
+	 */
 	if (tsc_khz == 0)
 		tsc_khz = cpu_khz;
+	else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz)
+		cpu_khz = tsc_khz;
 
 	if (!tsc_khz) {
 		mark_tsc_unstable("could not calculate TSC khz");

^ permalink raw reply related	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2016-07-11 19:35 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-17  5:22 [PATCH 0/10] x86/tsc: fast calibration updates Len Brown
2016-06-17  5:22 ` [PATCH 01/10] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" Len Brown
2016-06-17  5:22   ` [PATCH 02/10] x86 tsc_msr: Identify Intel-specific code Len Brown
2016-07-10 18:10     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
2016-06-17  5:22   ` [PATCH 03/10] x86 tsc_msr: Remove debugging messages Len Brown
2016-07-10 18:10     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
2016-06-17  5:22   ` [PATCH 04/10] x86 tsc_msr: Update comments, expand definitions Len Brown
2016-07-10 18:11     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
2016-06-17  5:22   ` [PATCH 05/10] x86 tsc_msr: Correct Silvermont reference clock values Len Brown
2016-07-10 18:11     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
2016-06-17  5:22   ` [PATCH 06/10] x86 tsc_msr: Add Airmont " Len Brown
2016-07-10 18:12     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
2016-06-17  5:22   ` [PATCH 07/10] x86 tsc_msr: Extend to include Intel Core Architecture Len Brown
2016-07-10 18:12     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
2016-06-17  5:22   ` [PATCH 08/10] x86 tsc_msr: Remove irqoff around MSR-based TSC enumeration Len Brown
2016-07-10 18:12     ` [tip:x86/timers] x86/tsc_msr: " tip-bot for Len Brown
2016-07-11 19:33     ` tip-bot for Len Brown
2016-06-17  5:22   ` [PATCH 09/10] x86 tsc: enumerate SKL cpu_khz and tsc_khz via CPUID Len Brown
2016-07-10 18:13     ` [tip:x86/timers] x86/tsc: Enumerate " tip-bot for Len Brown
2016-07-11 19:34     ` tip-bot for Len Brown
2016-06-17  5:22   ` [PATCH 10/10] x86 tsc: enumerate BXT " Len Brown
2016-07-10 18:13     ` [tip:x86/timers] x86/tsc: Enumerate " tip-bot for Len Brown
2016-07-11 19:34     ` tip-bot for Len Brown
2016-07-10 18:09   ` [tip:x86/timers] Revert "x86/tsc: Add missing Cherrytrail frequency to the table" tip-bot for Len Brown
2016-06-17  7:36 ` [PATCH 0/10] x86/tsc: fast calibration updates Thomas Gleixner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.