2 * This file is part of the coreboot project.
4 * Copyright (C) 2017-2019 Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <arch/intel-family.h>
19 #include <cpu/x86/msr.h>
20 #include <cpu/x86/tsc.h>
21 #include <intelblocks/msr.h>
23 static int get_processor_model(void)
27 get_fms(&c
, cpuid_eax(1));
33 * Nominal TSC frequency = "core crystal clock frequency" * EBX/EAX
36 * CPUID Initial EAX value = 0x15
37 * EAX Bit 31-0 : An unsigned integer which is the denominator of the
38 * TSC/"core crystal clock" ratio
39 * EBX Bit 31-0 : An unsigned integer which is the numerator of the
40 * TSC/"core crystal clock" ratio
41 * ECX Bit 31-0 : An unsigned integer which is the nominal frequency of the
42 * core crystal clock in Hz.
43 * EDX Bit 31-0 : Reserved = 0
45 * Refer to Intel SDM Jan 2019 Vol 3B Section 18.7.3
47 unsigned long tsc_freq_mhz(void)
49 unsigned int core_crystal_nominal_freq_khz
;
50 struct cpuid_result cpuidr
;
52 /* CPUID 15H TSC/Crystal ratio, plus optionally Crystal Hz */
55 if (!cpuidr
.ebx
|| !cpuidr
.eax
)
58 core_crystal_nominal_freq_khz
= cpuidr
.ecx
/ 1000;
60 if (!core_crystal_nominal_freq_khz
) {
61 switch (get_processor_model()) {
62 case CPU_MODEL_INTEL_SKYLAKE_MOBILE
:
63 case CPU_MODEL_INTEL_SKYLAKE_DESKTOP
:
64 case CPU_MODEL_INTEL_KABYLAKE_MOBILE
:
65 case CPU_MODEL_INTEL_KABYLAKE_DESKTOP
:
66 case CPU_MODEL_INTEL_CANNONLAKE_MOBILE
:
67 case CPU_MODEL_INTEL_ICELAKE_MOBILE
:
68 core_crystal_nominal_freq_khz
= 24000;
70 case CPU_MODEL_INTEL_ATOM_DENVERTON
:
71 core_crystal_nominal_freq_khz
= 25000;
73 case CPU_MODEL_INTEL_ATOM_GOLDMONT
:
74 case CPU_MODEL_INTEL_ATOM_GEMINI_LAKE
:
75 core_crystal_nominal_freq_khz
= 19200;
80 return (core_crystal_nominal_freq_khz
* cpuidr
.ebx
/ cpuidr
.eax
) /