From 3df39ef10704e82a61972fe2f71b6ff4466b7724 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 15 Aug 2017 22:41:50 -0700 Subject: x86: tsc: Add Airmont reference clock values Per the Intel 64 and IA-32 Architecture Software Developer's Manual, add the reference clock for Intel Atom Processors based on the Airmont Microarchitecture (Braswell). This keeps in sync with Linux kernel commit: 6fcb41c: x86/tsc_msr: Add Airmont reference clock values Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- drivers/timer/tsc_timer.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/timer') diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index 4d1fc9cd137..77040afafe7 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -18,7 +18,7 @@ #include #include -#define MAX_NUM_FREQS 8 +#define MAX_NUM_FREQS 9 DECLARE_GLOBAL_DATA_PTR; @@ -40,17 +40,20 @@ struct freq_desc { static struct freq_desc freq_desc_tables[] = { /* PNW */ - { 6, 0x27, 0, { 0, 0, 0, 0, 0, 99840, 0, 83200 } }, + { 6, 0x27, 0, { 0, 0, 0, 0, 0, 99840, 0, 83200, 0 } }, /* CLV+ */ - { 6, 0x35, 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200 } }, + { 6, 0x35, 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200, 0 } }, /* TNG - Intel Atom processor Z3400 series */ - { 6, 0x4a, 1, { 0, 100000, 133300, 0, 0, 0, 0, 0 } }, + { 6, 0x4a, 1, { 0, 100000, 133300, 0, 0, 0, 0, 0, 0 } }, /* VLV2 - Intel Atom processor E3000, Z3600, Z3700 series */ - { 6, 0x37, 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 } }, + { 6, 0x37, 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0, 0 } }, /* ANN - Intel Atom processor Z3500 series */ - { 6, 0x5a, 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0 } }, + { 6, 0x5a, 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0, 0 } }, + /* AMT - Intel Atom processor X7-Z8000 and X5-Z8000 series */ + { 6, 0x4c, 1, { 83300, 100000, 133300, 116700, + 80000, 93300, 90000, 88900, 87500 } }, /* Ivybridge */ - { 6, 0x3a, 2, { 0, 0, 0, 0, 0, 0, 0, 0 } }, + { 6, 0x3a, 2, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, }; static int match_cpu(u8 family, u8 model) -- cgit v1.3.1 From 2ff50f5fa4009adf5e23a69a4269e6bb054edd79 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 5 Sep 2017 19:49:46 -0600 Subject: dm: x86: Allow TSC timer to be used before DM is ready With bootstage we need access to the timer before driver model is set up. To handle this, put the required state in global_data and provide a new function to set up the device, separate from the driver's probe() method. This will be used by the 'early' timer also. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/include/asm/global_data.h | 1 + drivers/timer/tsc_timer.c | 30 +++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'drivers/timer') diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 93a80fe2b6c..fcb6853a380 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -77,6 +77,7 @@ struct arch_global_data { uint8_t x86_mask; uint32_t x86_device; uint64_t tsc_base; /* Initial value returned by rdtsc() */ + unsigned long clock_rate; /* Clock rate of timer in Hz */ void *new_fdt; /* Relocated FDT */ uint32_t bist; /* Built-in self test value */ enum pei_boot_mode_t pei_boot_mode; diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index 77040afafe7..9296de65432 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -331,17 +331,17 @@ static int tsc_timer_get_count(struct udevice *dev, u64 *count) return 0; } -static int tsc_timer_probe(struct udevice *dev) +static void tsc_timer_ensure_setup(void) { - struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); - + if (gd->arch.tsc_base) + return; gd->arch.tsc_base = rdtsc(); /* * If there is no clock frequency specified in the device tree, * calibrate it by ourselves. */ - if (!uc_priv->clock_rate) { + if (!gd->arch.clock_rate) { unsigned long fast_calibrate; fast_calibrate = cpu_mhz_from_msr(); @@ -351,12 +351,32 @@ static int tsc_timer_probe(struct udevice *dev) panic("TSC frequency is ZERO"); } - uc_priv->clock_rate = fast_calibrate * 1000000; + gd->arch.clock_rate = fast_calibrate * 1000000; } +} + +static int tsc_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + tsc_timer_ensure_setup(); + uc_priv->clock_rate = gd->arch.clock_rate; return 0; } +unsigned long notrace timer_early_get_rate(void) +{ + tsc_timer_ensure_setup(); + + return gd->arch.clock_rate; +} + +u64 notrace timer_early_get_count(void) +{ + return rdtsc() - gd->arch.tsc_base; +} + static const struct timer_ops tsc_timer_ops = { .get_count = tsc_timer_get_count, }; -- cgit v1.3.1