aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/include/arch/intel-family.h86
-rw-r--r--src/soc/intel/common/block/timer/timer.c105
2 files changed, 75 insertions, 116 deletions
diff --git a/src/arch/x86/include/arch/intel-family.h b/src/arch/x86/include/arch/intel-family.h
deleted file mode 100644
index 43eb0e6b34..0000000000
--- a/src/arch/x86/include/arch/intel-family.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef ARCH_INTEL_FAMILY_H
-#define ARCH_INTEL_FAMILY_H
-
-#define CPU_MODEL_INTEL_CORE_YONAH 0x0E
-
-#define CPU_MODEL_INTEL_CORE2_MEROM 0x0F
-#define CPU_MODEL_INTEL_CORE2_MEROM_L 0x16
-#define CPU_MODEL_INTEL_CORE2_PENRYN 0x17
-#define CPU_MODEL_INTEL_CORE2_DUNNINGTON 0x1D
-
-#define CPU_MODEL_INTEL_NEHALEM 0x1E
-/* Auburndale / Havendale */
-#define CPU_MODEL_INTEL_NEHALEM_G 0x1F
-#define CPU_MODEL_INTEL_NEHALEM_EP 0x1A
-#define CPU_MODEL_INTEL_NEHALEM_EX 0x2E
-
-#define CPU_MODEL_INTEL_WESTMERE 0x25
-#define CPU_MODEL_INTEL_WESTMERE_EP 0x2C
-#define CPU_MODEL_INTEL_WESTMERE_EX 0x2F
-
-#define CPU_MODEL_INTEL_SANDYBRIDGE 0x2A
-#define CPU_MODEL_INTEL_SANDYBRIDGE_X 0x2D
-#define CPU_MODEL_INTEL_IVYBRIDGE 0x3A
-#define CPU_MODEL_INTEL_IVYBRIDGE_X 0x3E
-
-#define CPU_MODEL_INTEL_HASWELL_CORE 0x3C
-#define CPU_MODEL_INTEL_HASWELL_X 0x3F
-#define CPU_MODEL_INTEL_HASWELL_ULT 0x45
-#define CPU_MODEL_INTEL_HASWELL_GT3E 0x46
-
-#define CPU_MODEL_INTEL_BROADWELL_CORE 0x3D
-#define CPU_MODEL_INTEL_BROADWELL_GT3E 0x47
-#define CPU_MODEL_INTEL_BROADWELL_X 0x4F
-#define CPU_MODEL_INTEL_BROADWELL_XEON_D 0x56
-
-#define CPU_MODEL_INTEL_SKYLAKE_MOBILE 0x4E
-#define CPU_MODEL_INTEL_SKYLAKE_DESKTOP 0x5E
-#define CPU_MODEL_INTEL_SKYLAKE_X 0x55
-#define CPU_MODEL_INTEL_KABYLAKE_MOBILE 0x8E
-#define CPU_MODEL_INTEL_KABYLAKE_DESKTOP 0x9E
-#define CPU_MODEL_INTEL_CANNONLAKE_MOBILE 0x66
-#define CPU_MODEL_INTEL_ICELAKE_MOBILE 0x7E
-
-/* "Small Core" Processors (Atom) */
-
-#define CPU_MODEL_INTEL_ATOM_PINEVIEW 0x1C
-#define CPU_MODEL_INTEL_ATOM_LINCROFT 0x26
-#define CPU_MODEL_INTEL_ATOM_PENWELL 0x27
-#define CPU_MODEL_INTEL_ATOM_CLOVERVIEW 0x35
-#define CPU_MODEL_INTEL_ATOM_CEDARVIEW 0x36
-/* BayTrail/BYT / Valleyview */
-#define CPU_MODEL_INTEL_ATOM_SILVERMONT1 0x37
-/* Avaton/Rangely */
-#define CPU_MODEL_INTEL_ATOM_SILVERMONT2 0x4D
-/* CherryTrail / Braswell */
-#define CPU_MODEL_INTEL_ATOM_AIRMONT 0x4C
-/* Tangier */
-#define CPU_MODEL_INTEL_ATOM_MERRIFIELD 0x4A
-/* Anniedale */
-#define CPU_MODEL_INTEL_ATOM_MOOREFIELD 0x5A
-#define CPU_MODEL_INTEL_ATOM_GOLDMONT 0x5C
-/* Goldmont Microserver */
-#define CPU_MODEL_INTEL_ATOM_DENVERTON 0x5F
-#define CPU_MODEL_INTEL_ATOM_GEMINI_LAKE 0x7A
-
-/* Xeon Phi */
-
-/* Knights Landing */
-#define CPU_MODEL_INTEL_XEON_PHI_KNL 0x57
-/* Knights Mill */
-#define CPU_MODEL_INTEL_XEON_PHI_KNM 0x85
-
-#endif /* ARCH_INTEL_FAMILY_H */
diff --git a/src/soc/intel/common/block/timer/timer.c b/src/soc/intel/common/block/timer/timer.c
index e60ac4d26d..8fde5419d3 100644
--- a/src/soc/intel/common/block/timer/timer.c
+++ b/src/soc/intel/common/block/timer/timer.c
@@ -14,12 +14,14 @@
*/
#include <arch/cpu.h>
-#include <arch/intel-family.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/tsc.h>
#include <intelblocks/msr.h>
+/* Goldmont Microserver */
+#define CPU_MODEL_INTEL_ATOM_DENVERTON 0x5F
+
static int get_processor_model(void)
{
struct cpuinfo_x86 c;
@@ -29,8 +31,31 @@ static int get_processor_model(void)
return c.x86_model;
}
+static unsigned int get_max_cpuid_func(void)
+{
+ return cpuid_eax(0);
+}
+
+static unsigned long get_hardcoded_crystal_freq(void)
+{
+ unsigned int core_crystal_nominal_freq_khz;
+
+ /*
+ * Denverton SoCs don't report crystal clock, and also don't support
+ * CPUID.0x16, so hardcode the 25MHz crystal clock.
+ */
+ switch (get_processor_model()) {
+ case CPU_MODEL_INTEL_ATOM_DENVERTON:
+ core_crystal_nominal_freq_khz = 25000;
+ break;
+ }
+
+ return core_crystal_nominal_freq_khz;
+}
+
/*
- * Nominal TSC frequency = "core crystal clock frequency" * EBX/EAX
+ * Nominal TSC frequency = "core crystal clock frequency" *
+ * CPUID_15h.EBX/CPUID_15h.EAX
*
* Time Stamp Counter
* CPUID Initial EAX value = 0x15
@@ -42,41 +67,61 @@ static int get_processor_model(void)
* core crystal clock in Hz.
* EDX Bit 31-0 : Reserved = 0
*
- * Refer to Intel SDM Jan 2019 Vol 3B Section 18.7.3
*/
-unsigned long tsc_freq_mhz(void)
+static unsigned long calculate_tsc_freq_from_core_crystal(void)
{
unsigned int core_crystal_nominal_freq_khz;
- struct cpuid_result cpuidr;
+ struct cpuid_result cpuidr_15h;
+
+ if (get_max_cpuid_func() < 0x15)
+ return 0;
/* CPUID 15H TSC/Crystal ratio, plus optionally Crystal Hz */
- cpuidr = cpuid(0x15);
+ cpuidr_15h = cpuid(0x15);
- if (!cpuidr.ebx || !cpuidr.eax)
+ if (!cpuidr_15h.ebx || !cpuidr_15h.eax)
return 0;
- core_crystal_nominal_freq_khz = cpuidr.ecx / 1000;
-
- if (!core_crystal_nominal_freq_khz) {
- switch (get_processor_model()) {
- case CPU_MODEL_INTEL_SKYLAKE_MOBILE:
- case CPU_MODEL_INTEL_SKYLAKE_DESKTOP:
- case CPU_MODEL_INTEL_KABYLAKE_MOBILE:
- case CPU_MODEL_INTEL_KABYLAKE_DESKTOP:
- case CPU_MODEL_INTEL_CANNONLAKE_MOBILE:
- case CPU_MODEL_INTEL_ICELAKE_MOBILE:
- core_crystal_nominal_freq_khz = 24000;
- break;
- case CPU_MODEL_INTEL_ATOM_DENVERTON:
- core_crystal_nominal_freq_khz = 25000;
- break;
- case CPU_MODEL_INTEL_ATOM_GOLDMONT:
- case CPU_MODEL_INTEL_ATOM_GEMINI_LAKE:
- core_crystal_nominal_freq_khz = 19200;
- break;
- }
- }
+ core_crystal_nominal_freq_khz = cpuidr_15h.ecx / 1000;
+
+ if (!core_crystal_nominal_freq_khz)
+ core_crystal_nominal_freq_khz = get_hardcoded_crystal_freq();
+
+ return (core_crystal_nominal_freq_khz * cpuidr_15h.ebx /
+ cpuidr_15h.eax) / 1000;
+}
+
+/*
+ * Processor Frequency Information
+ * CPUID Initial EAX value = 0x16
+ * EAX Bit 31-0 : An unsigned integer which has the processor base frequency
+ * information
+ * EBX Bit 31-0 : An unsigned integer which has maximum frequency information
+ * ECX Bit 31-0 : An unsigned integer which has bus frequency information
+ * EDX Bit 31-0 : Reserved = 0
+ *
+ * Refer to Intel SDM Jan 2019 Vol 3B Section 18.7.3
+ */
+static unsigned long get_freq_from_cpuid16h(void)
+{
+ if (get_max_cpuid_func() < 0x16)
+ return 0;
+
+ return cpuid_eax(0x16);
+}
+
+unsigned long tsc_freq_mhz(void)
+{
+ unsigned long tsc_freq;
+
+ tsc_freq = calculate_tsc_freq_from_core_crystal();
+
+ if (tsc_freq)
+ return tsc_freq;
- return (core_crystal_nominal_freq_khz * cpuidr.ebx / cpuidr.eax) /
- 1000;
+ /*
+ * Some Intel SoCs like Skylake, Kabylake and Cometlake don't report
+ * the crystal clock, in that case return bus frequency using CPUID.16h
+ */
+ return get_freq_from_cpuid16h();
}