1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <cpu/x86/tsc.h>
5 #include <intelblocks/msr.h>
7 /* Goldmont Microserver */
8 #define CPU_MODEL_INTEL_ATOM_DENVERTON 0x5F
10 static int get_processor_model(void)
14 get_fms(&c
, cpuid_eax(1));
19 static unsigned long get_hardcoded_crystal_freq(void)
21 unsigned long core_crystal_nominal_freq_khz
= 0;
24 * Denverton SoCs don't report crystal clock, and also don't support
25 * CPUID.0x16, so hardcode the 25MHz crystal clock.
27 switch (get_processor_model()) {
28 case CPU_MODEL_INTEL_ATOM_DENVERTON
:
29 core_crystal_nominal_freq_khz
= 25000;
33 return core_crystal_nominal_freq_khz
;
37 * Nominal TSC frequency = "core crystal clock frequency" *
38 * CPUID_15h.EBX/CPUID_15h.EAX
41 * CPUID Initial EAX value = 0x15
42 * EAX Bit 31-0 : An unsigned integer which is the denominator of the
43 * TSC/"core crystal clock" ratio
44 * EBX Bit 31-0 : An unsigned integer which is the numerator of the
45 * TSC/"core crystal clock" ratio
46 * ECX Bit 31-0 : An unsigned integer which is the nominal frequency of the
47 * core crystal clock in Hz.
48 * EDX Bit 31-0 : Reserved = 0
51 static unsigned long calculate_tsc_freq_from_core_crystal(void)
53 unsigned long core_crystal_nominal_freq_khz
;
54 struct cpuid_result cpuidr_15h
;
56 if (cpuid_get_max_func() < 0x15)
59 /* CPUID 15H TSC/Crystal ratio, plus optionally Crystal Hz */
60 cpuidr_15h
= cpuid(0x15);
62 if (!cpuidr_15h
.ebx
|| !cpuidr_15h
.eax
)
65 core_crystal_nominal_freq_khz
= cpuidr_15h
.ecx
/ 1000;
67 if (!core_crystal_nominal_freq_khz
)
68 core_crystal_nominal_freq_khz
= get_hardcoded_crystal_freq();
70 return (core_crystal_nominal_freq_khz
* cpuidr_15h
.ebx
/
71 cpuidr_15h
.eax
) / 1000;
75 * Processor Frequency Information
76 * CPUID Initial EAX value = 0x16
77 * EAX Bit 31-0 : An unsigned integer which has the processor base frequency
79 * EBX Bit 31-0 : An unsigned integer which has maximum frequency information
80 * ECX Bit 31-0 : An unsigned integer which has bus frequency information
81 * EDX Bit 31-0 : Reserved = 0
83 * Refer to Intel SDM Jan 2019 Vol 3B Section 18.7.3
85 static unsigned long get_freq_from_cpuid16h(void)
87 if (cpuid_get_max_func() < 0x16)
90 return cpuid_eax(0x16);
93 unsigned long tsc_freq_mhz(void)
95 unsigned long tsc_freq
;
97 tsc_freq
= calculate_tsc_freq_from_core_crystal();
103 * Some Intel SoCs like Skylake, Kabylake and Cometlake don't report
104 * the crystal clock, in that case return bus frequency using CPUID.16h
106 return get_freq_from_cpuid16h();