Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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