xref: /OK3568_Linux_fs/kernel/arch/x86/kernel/tsc_msr.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * TSC frequency enumeration via MSR
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2013, 2018 Intel Corporation
6*4882a593Smuzhiyun  * Author: Bin Gao <bin.gao@intel.com>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/thread_info.h>
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <asm/apic.h>
13*4882a593Smuzhiyun #include <asm/cpu_device_id.h>
14*4882a593Smuzhiyun #include <asm/intel-family.h>
15*4882a593Smuzhiyun #include <asm/msr.h>
16*4882a593Smuzhiyun #include <asm/param.h>
17*4882a593Smuzhiyun #include <asm/tsc.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define MAX_NUM_FREQS	16 /* 4 bits to select the frequency */
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /*
22*4882a593Smuzhiyun  * The frequency numbers in the SDM are e.g. 83.3 MHz, which does not contain a
23*4882a593Smuzhiyun  * lot of accuracy which leads to clock drift. As far as we know Bay Trail SoCs
24*4882a593Smuzhiyun  * use a 25 MHz crystal and Cherry Trail uses a 19.2 MHz crystal, the crystal
25*4882a593Smuzhiyun  * is the source clk for a root PLL which outputs 1600 and 100 MHz. It is
26*4882a593Smuzhiyun  * unclear if the root PLL outputs are used directly by the CPU clock PLL or
27*4882a593Smuzhiyun  * if there is another PLL in between.
28*4882a593Smuzhiyun  * This does not matter though, we can model the chain of PLLs as a single PLL
29*4882a593Smuzhiyun  * with a quotient equal to the quotients of all PLLs in the chain multiplied.
30*4882a593Smuzhiyun  * So we can create a simplified model of the CPU clock setup using a reference
31*4882a593Smuzhiyun  * clock of 100 MHz plus a quotient which gets us as close to the frequency
32*4882a593Smuzhiyun  * from the SDM as possible.
33*4882a593Smuzhiyun  * For the 83.3 MHz example from above this would give us 100 MHz * 5 / 6 =
34*4882a593Smuzhiyun  * 83 and 1/3 MHz, which matches exactly what has been measured on actual hw.
35*4882a593Smuzhiyun  */
36*4882a593Smuzhiyun #define TSC_REFERENCE_KHZ 100000
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun struct muldiv {
39*4882a593Smuzhiyun 	u32 multiplier;
40*4882a593Smuzhiyun 	u32 divider;
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun /*
44*4882a593Smuzhiyun  * If MSR_PERF_STAT[31] is set, the maximum resolved bus ratio can be
45*4882a593Smuzhiyun  * read in MSR_PLATFORM_ID[12:8], otherwise in MSR_PERF_STAT[44:40].
46*4882a593Smuzhiyun  * Unfortunately some Intel Atom SoCs aren't quite compliant to this,
47*4882a593Smuzhiyun  * so we need manually differentiate SoC families. This is what the
48*4882a593Smuzhiyun  * field use_msr_plat does.
49*4882a593Smuzhiyun  */
50*4882a593Smuzhiyun struct freq_desc {
51*4882a593Smuzhiyun 	bool use_msr_plat;
52*4882a593Smuzhiyun 	struct muldiv muldiv[MAX_NUM_FREQS];
53*4882a593Smuzhiyun 	/*
54*4882a593Smuzhiyun 	 * Some CPU frequencies in the SDM do not map to known PLL freqs, in
55*4882a593Smuzhiyun 	 * that case the muldiv array is empty and the freqs array is used.
56*4882a593Smuzhiyun 	 */
57*4882a593Smuzhiyun 	u32 freqs[MAX_NUM_FREQS];
58*4882a593Smuzhiyun 	u32 mask;
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /*
62*4882a593Smuzhiyun  * Penwell and Clovertrail use spread spectrum clock,
63*4882a593Smuzhiyun  * so the freq number is not exactly the same as reported
64*4882a593Smuzhiyun  * by MSR based on SDM.
65*4882a593Smuzhiyun  */
66*4882a593Smuzhiyun static const struct freq_desc freq_desc_pnw = {
67*4882a593Smuzhiyun 	.use_msr_plat = false,
68*4882a593Smuzhiyun 	.freqs = { 0, 0, 0, 0, 0, 99840, 0, 83200 },
69*4882a593Smuzhiyun 	.mask = 0x07,
70*4882a593Smuzhiyun };
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun static const struct freq_desc freq_desc_clv = {
73*4882a593Smuzhiyun 	.use_msr_plat = false,
74*4882a593Smuzhiyun 	.freqs = { 0, 133200, 0, 0, 0, 99840, 0, 83200 },
75*4882a593Smuzhiyun 	.mask = 0x07,
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /*
79*4882a593Smuzhiyun  * Bay Trail SDM MSR_FSB_FREQ frequencies simplified PLL model:
80*4882a593Smuzhiyun  *  000:   100 *  5 /  6  =  83.3333 MHz
81*4882a593Smuzhiyun  *  001:   100 *  1 /  1  = 100.0000 MHz
82*4882a593Smuzhiyun  *  010:   100 *  4 /  3  = 133.3333 MHz
83*4882a593Smuzhiyun  *  011:   100 *  7 /  6  = 116.6667 MHz
84*4882a593Smuzhiyun  *  100:   100 *  4 /  5  =  80.0000 MHz
85*4882a593Smuzhiyun  */
86*4882a593Smuzhiyun static const struct freq_desc freq_desc_byt = {
87*4882a593Smuzhiyun 	.use_msr_plat = true,
88*4882a593Smuzhiyun 	.muldiv = { { 5, 6 }, { 1, 1 }, { 4, 3 }, { 7, 6 },
89*4882a593Smuzhiyun 		    { 4, 5 } },
90*4882a593Smuzhiyun 	.mask = 0x07,
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun /*
94*4882a593Smuzhiyun  * Cherry Trail SDM MSR_FSB_FREQ frequencies simplified PLL model:
95*4882a593Smuzhiyun  * 0000:   100 *  5 /  6  =  83.3333 MHz
96*4882a593Smuzhiyun  * 0001:   100 *  1 /  1  = 100.0000 MHz
97*4882a593Smuzhiyun  * 0010:   100 *  4 /  3  = 133.3333 MHz
98*4882a593Smuzhiyun  * 0011:   100 *  7 /  6  = 116.6667 MHz
99*4882a593Smuzhiyun  * 0100:   100 *  4 /  5  =  80.0000 MHz
100*4882a593Smuzhiyun  * 0101:   100 * 14 / 15  =  93.3333 MHz
101*4882a593Smuzhiyun  * 0110:   100 *  9 / 10  =  90.0000 MHz
102*4882a593Smuzhiyun  * 0111:   100 *  8 /  9  =  88.8889 MHz
103*4882a593Smuzhiyun  * 1000:   100 *  7 /  8  =  87.5000 MHz
104*4882a593Smuzhiyun  */
105*4882a593Smuzhiyun static const struct freq_desc freq_desc_cht = {
106*4882a593Smuzhiyun 	.use_msr_plat = true,
107*4882a593Smuzhiyun 	.muldiv = { { 5, 6 }, {  1,  1 }, { 4,  3 }, { 7, 6 },
108*4882a593Smuzhiyun 		    { 4, 5 }, { 14, 15 }, { 9, 10 }, { 8, 9 },
109*4882a593Smuzhiyun 		    { 7, 8 } },
110*4882a593Smuzhiyun 	.mask = 0x0f,
111*4882a593Smuzhiyun };
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun /*
114*4882a593Smuzhiyun  * Merriefield SDM MSR_FSB_FREQ frequencies simplified PLL model:
115*4882a593Smuzhiyun  * 0001:   100 *  1 /  1  = 100.0000 MHz
116*4882a593Smuzhiyun  * 0010:   100 *  4 /  3  = 133.3333 MHz
117*4882a593Smuzhiyun  */
118*4882a593Smuzhiyun static const struct freq_desc freq_desc_tng = {
119*4882a593Smuzhiyun 	.use_msr_plat = true,
120*4882a593Smuzhiyun 	.muldiv = { { 0, 0 }, { 1, 1 }, { 4, 3 } },
121*4882a593Smuzhiyun 	.mask = 0x07,
122*4882a593Smuzhiyun };
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun /*
125*4882a593Smuzhiyun  * Moorefield SDM MSR_FSB_FREQ frequencies simplified PLL model:
126*4882a593Smuzhiyun  * 0000:   100 *  5 /  6  =  83.3333 MHz
127*4882a593Smuzhiyun  * 0001:   100 *  1 /  1  = 100.0000 MHz
128*4882a593Smuzhiyun  * 0010:   100 *  4 /  3  = 133.3333 MHz
129*4882a593Smuzhiyun  * 0011:   100 *  1 /  1  = 100.0000 MHz
130*4882a593Smuzhiyun  */
131*4882a593Smuzhiyun static const struct freq_desc freq_desc_ann = {
132*4882a593Smuzhiyun 	.use_msr_plat = true,
133*4882a593Smuzhiyun 	.muldiv = { { 5, 6 }, { 1, 1 }, { 4, 3 }, { 1, 1 } },
134*4882a593Smuzhiyun 	.mask = 0x0f,
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /*
138*4882a593Smuzhiyun  * 24 MHz crystal? : 24 * 13 / 4 = 78 MHz
139*4882a593Smuzhiyun  * Frequency step for Lightning Mountain SoC is fixed to 78 MHz,
140*4882a593Smuzhiyun  * so all the frequency entries are 78000.
141*4882a593Smuzhiyun  */
142*4882a593Smuzhiyun static const struct freq_desc freq_desc_lgm = {
143*4882a593Smuzhiyun 	.use_msr_plat = true,
144*4882a593Smuzhiyun 	.freqs = { 78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000,
145*4882a593Smuzhiyun 		   78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000 },
146*4882a593Smuzhiyun 	.mask = 0x0f,
147*4882a593Smuzhiyun };
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun static const struct x86_cpu_id tsc_msr_cpu_ids[] = {
150*4882a593Smuzhiyun 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL_MID,	&freq_desc_pnw),
151*4882a593Smuzhiyun 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL_TABLET,&freq_desc_clv),
152*4882a593Smuzhiyun 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT,	&freq_desc_byt),
153*4882a593Smuzhiyun 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID,	&freq_desc_tng),
154*4882a593Smuzhiyun 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT,	&freq_desc_cht),
155*4882a593Smuzhiyun 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT_MID,	&freq_desc_ann),
156*4882a593Smuzhiyun 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT_NP,	&freq_desc_lgm),
157*4882a593Smuzhiyun 	{}
158*4882a593Smuzhiyun };
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /*
161*4882a593Smuzhiyun  * MSR-based CPU/TSC frequency discovery for certain CPUs.
162*4882a593Smuzhiyun  *
163*4882a593Smuzhiyun  * Set global "lapic_timer_period" to bus_clock_cycles/jiffy
164*4882a593Smuzhiyun  * Return processor base frequency in KHz, or 0 on failure.
165*4882a593Smuzhiyun  */
cpu_khz_from_msr(void)166*4882a593Smuzhiyun unsigned long cpu_khz_from_msr(void)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	u32 lo, hi, ratio, freq, tscref;
169*4882a593Smuzhiyun 	const struct freq_desc *freq_desc;
170*4882a593Smuzhiyun 	const struct x86_cpu_id *id;
171*4882a593Smuzhiyun 	const struct muldiv *md;
172*4882a593Smuzhiyun 	unsigned long res;
173*4882a593Smuzhiyun 	int index;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	id = x86_match_cpu(tsc_msr_cpu_ids);
176*4882a593Smuzhiyun 	if (!id)
177*4882a593Smuzhiyun 		return 0;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	freq_desc = (struct freq_desc *)id->driver_data;
180*4882a593Smuzhiyun 	if (freq_desc->use_msr_plat) {
181*4882a593Smuzhiyun 		rdmsr(MSR_PLATFORM_INFO, lo, hi);
182*4882a593Smuzhiyun 		ratio = (lo >> 8) & 0xff;
183*4882a593Smuzhiyun 	} else {
184*4882a593Smuzhiyun 		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
185*4882a593Smuzhiyun 		ratio = (hi >> 8) & 0x1f;
186*4882a593Smuzhiyun 	}
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	/* Get FSB FREQ ID */
189*4882a593Smuzhiyun 	rdmsr(MSR_FSB_FREQ, lo, hi);
190*4882a593Smuzhiyun 	index = lo & freq_desc->mask;
191*4882a593Smuzhiyun 	md = &freq_desc->muldiv[index];
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/*
194*4882a593Smuzhiyun 	 * Note this also catches cases where the index points to an unpopulated
195*4882a593Smuzhiyun 	 * part of muldiv, in that case the else will set freq and res to 0.
196*4882a593Smuzhiyun 	 */
197*4882a593Smuzhiyun 	if (md->divider) {
198*4882a593Smuzhiyun 		tscref = TSC_REFERENCE_KHZ * md->multiplier;
199*4882a593Smuzhiyun 		freq = DIV_ROUND_CLOSEST(tscref, md->divider);
200*4882a593Smuzhiyun 		/*
201*4882a593Smuzhiyun 		 * Multiplying by ratio before the division has better
202*4882a593Smuzhiyun 		 * accuracy than just calculating freq * ratio.
203*4882a593Smuzhiyun 		 */
204*4882a593Smuzhiyun 		res = DIV_ROUND_CLOSEST(tscref * ratio, md->divider);
205*4882a593Smuzhiyun 	} else {
206*4882a593Smuzhiyun 		freq = freq_desc->freqs[index];
207*4882a593Smuzhiyun 		res = freq * ratio;
208*4882a593Smuzhiyun 	}
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	if (freq == 0)
211*4882a593Smuzhiyun 		pr_err("Error MSR_FSB_FREQ index %d is unknown\n", index);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun #ifdef CONFIG_X86_LOCAL_APIC
214*4882a593Smuzhiyun 	lapic_timer_period = (freq * 1000) / HZ;
215*4882a593Smuzhiyun #endif
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	/*
218*4882a593Smuzhiyun 	 * TSC frequency determined by MSR is always considered "known"
219*4882a593Smuzhiyun 	 * because it is reported by HW.
220*4882a593Smuzhiyun 	 * Another fact is that on MSR capable platforms, PIT/HPET is
221*4882a593Smuzhiyun 	 * generally not available so calibration won't work at all.
222*4882a593Smuzhiyun 	 */
223*4882a593Smuzhiyun 	setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	/*
226*4882a593Smuzhiyun 	 * Unfortunately there is no way for hardware to tell whether the
227*4882a593Smuzhiyun 	 * TSC is reliable.  We were told by silicon design team that TSC
228*4882a593Smuzhiyun 	 * on Atom SoCs are always "reliable". TSC is also the only
229*4882a593Smuzhiyun 	 * reliable clocksource on these SoCs (HPET is either not present
230*4882a593Smuzhiyun 	 * or not functional) so mark TSC reliable which removes the
231*4882a593Smuzhiyun 	 * requirement for a watchdog clocksource.
232*4882a593Smuzhiyun 	 */
233*4882a593Smuzhiyun 	setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	return res;
236*4882a593Smuzhiyun }
237