soc/intel/common/timer: Calculate TSC frequency based on CPUID 0x15
[coreboot.git] / src / soc / intel / common / block / timer / timer.c
blobe60ac4d26df3ea35443ea38dcb7e9603b1b4e5a3
1 /*
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.
16 #include <arch/cpu.h>
17 #include <arch/intel-family.h>
18 #include <cpu/cpu.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)
25 struct cpuinfo_x86 c;
27 get_fms(&c, cpuid_eax(1));
29 return c.x86_model;
33 * Nominal TSC frequency = "core crystal clock frequency" * EBX/EAX
35 * Time Stamp Counter
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 */
53 cpuidr = cpuid(0x15);
55 if (!cpuidr.ebx || !cpuidr.eax)
56 return 0;
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;
69 break;
70 case CPU_MODEL_INTEL_ATOM_DENVERTON:
71 core_crystal_nominal_freq_khz = 25000;
72 break;
73 case CPU_MODEL_INTEL_ATOM_GOLDMONT:
74 case CPU_MODEL_INTEL_ATOM_GEMINI_LAKE:
75 core_crystal_nominal_freq_khz = 19200;
76 break;
80 return (core_crystal_nominal_freq_khz * cpuidr.ebx / cpuidr.eax) /
81 1000;