diff options
-rw-r--r-- | src/arch/x86/include/arch/intel-family.h | 86 | ||||
-rw-r--r-- | src/soc/intel/common/block/timer/timer.c | 105 |
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(); } |