[U-Boot] [PATCH v2] x86: tsc: Add support for native calibration of TSC freq
Bin Meng
bmeng.cn at gmail.com
Fri Dec 21 13:08:48 UTC 2018
Hi Bernhard,
On Fri, Dec 21, 2018 at 3:31 PM Bernhard Messerklinger
<bernhard.messerklinger at br-automation.com> wrote:
>
> Add native tsc calibration function. Calibrate the tsc timer the same
> way as linux does arch/x86/kernel/tsc.c.
nits: does in arch/x86/kernel/tsc.c
> Fixes booting for Apollo Lake processors.
>
> Signed-off-by: Bernhard Messerklinger <bernhard.messerklinger at br-automation.com>
> ---
> I hope this patch won't break other x86 board.
> I only can test it with APL board.
>
> Changes in v1:
> - Update to linux way of dealing with TSC calibration
>
> drivers/timer/tsc_timer.c | 52 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 52 insertions(+)
>
> diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
> index ba940ebf1c..ec7f05db17 100644
> --- a/drivers/timer/tsc_timer.c
> +++ b/drivers/timer/tsc_timer.c
> @@ -19,8 +19,56 @@
>
> #define MAX_NUM_FREQS 9
>
> +#define INTEL_FAM6_SKYLAKE_MOBILE 0x4E
> +#define INTEL_FAM6_ATOM_GOLDMONT 0x5C /* Apollo Lake */
> +#define INTEL_FAM6_SKYLAKE_DESKTOP 0x5E
> +#define INTEL_FAM6_KABYLAKE_MOBILE 0x8E
> +#define INTEL_FAM6_KABYLAKE_DESKTOP 0x9E
> +#define INTEL_FAM6_ATOM_DENVERTON 0x5F /* Goldmont Microserver */
Linux uses the macro name INTEL_FAM6_ATOM_GOLDMONT_X. Can we use
exactly the same name to keep in sync? Also please use the same
comments as Linux.
> +
nits: Can we sort the numbers here?
> DECLARE_GLOBAL_DATA_PTR;
>
> +/*
> + * native_calibrate_tsc
> + * Determine TSC frequency via CPUID, else return 0.
> + */
> +static unsigned long native_calibrate_tsc(void)
> +{
> + struct cpuid_result tsc_info;
> + unsigned int crystal_freq;
> +
> + if (gd->arch.x86_vendor != X86_VENDOR_INTEL)
> + return 0;
> +
> + if (cpuid_eax(0) < 0x15)
> + return 0;
> +
> + tsc_info = cpuid(0x15);
> +
> + crystal_freq = tsc_info.ecx / 1000;
> +
Missing checking tsc_info.eax and tsc_info.ebx here, like what is done
in Linux codes.
> + if (!crystal_freq) {
> + switch (gd->arch.x86_model) {
> + case INTEL_FAM6_SKYLAKE_MOBILE:
> + case INTEL_FAM6_SKYLAKE_DESKTOP:
> + case INTEL_FAM6_KABYLAKE_MOBILE:
> + case INTEL_FAM6_KABYLAKE_DESKTOP:
> + crystal_freq = 24000; /* 24.0 MHz */
> + break;
> + case INTEL_FAM6_ATOM_DENVERTON:
> + crystal_freq = 25000; /* 25.0 MHz */
> + break;
> + case INTEL_FAM6_ATOM_GOLDMONT:
> + crystal_freq = 19200; /* 19.2 MHz */
> + break;
> + default:
> + return 0;
> + }
> + }
> +
> + return (crystal_freq * tsc_info.ebx / tsc_info.eax) / 1000;
> +}
> +
> static unsigned long cpu_mhz_from_cpuid(void)
> {
> if (gd->arch.x86_vendor != X86_VENDOR_INTEL)
> @@ -350,6 +398,10 @@ static void tsc_timer_ensure_setup(bool early)
> if (!gd->arch.clock_rate) {
> unsigned long fast_calibrate;
>
> + fast_calibrate = native_calibrate_tsc();
> + if (fast_calibrate)
> + goto done;
> +
> fast_calibrate = cpu_mhz_from_cpuid();
> if (fast_calibrate)
> goto done;
> --
Regards,
Bin
More information about the U-Boot
mailing list