From 4e51fc2351abbb2ebe42fbedccfec3bba20b1c12 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 13 Nov 2015 00:11:21 -0800 Subject: [PATCH] x86: tsc: Add driver model timer support This adds driver model timer support to x86 tsc timer driver. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/lib/tsc_timer.c | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c index 5a962ce629..4a95959e1b 100644 --- a/arch/x86/lib/tsc_timer.c +++ b/arch/x86/lib/tsc_timer.c @@ -8,7 +8,9 @@ */ #include +#include #include +#include #include #include #include @@ -278,6 +280,7 @@ success: return delta / 1000; } +#ifndef CONFIG_TIMER void timer_set_base(u64 base) { gd->arch.tsc_base = base; @@ -297,10 +300,14 @@ u64 notrace get_ticks(void) panic("No tick base available"); return now_tick - gd->arch.tsc_base; } +#endif /* CONFIG_TIMER */ /* Get the speed of the TSC timer in MHz */ unsigned notrace long get_tbclk_mhz(void) { +#ifdef CONFIG_TIMER + return get_tbclk() / 1000000; +#else unsigned long fast_calibrate; if (gd->arch.tsc_mhz) @@ -320,12 +327,15 @@ unsigned notrace long get_tbclk_mhz(void) gd->arch.tsc_mhz = fast_calibrate; return fast_calibrate; +#endif } +#ifndef CONFIG_TIMER unsigned long get_tbclk(void) { return get_tbclk_mhz() * 1000 * 1000; } +#endif static ulong get_ms_timer(void) { @@ -375,3 +385,58 @@ int timer_init(void) return 0; } + +#ifdef CONFIG_TIMER +static int tsc_timer_get_count(struct udevice *dev, u64 *count) +{ + u64 now_tick = rdtsc(); + + *count = now_tick - gd->arch.tsc_base; + + return 0; +} + +static int tsc_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + 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) { + unsigned long fast_calibrate; + + fast_calibrate = try_msr_calibrate_tsc(); + if (!fast_calibrate) { + fast_calibrate = quick_pit_calibrate(); + if (!fast_calibrate) + panic("TSC frequency is ZERO"); + } + + uc_priv->clock_rate = fast_calibrate * 1000000; + } + + return 0; +} + +static const struct timer_ops tsc_timer_ops = { + .get_count = tsc_timer_get_count, +}; + +static const struct udevice_id tsc_timer_ids[] = { + { .compatible = "x86,tsc-timer", }, + { } +}; + +U_BOOT_DRIVER(tsc_timer) = { + .name = "tsc_timer", + .id = UCLASS_TIMER, + .of_match = tsc_timer_ids, + .probe = tsc_timer_probe, + .ops = &tsc_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +}; +#endif /* CONFIG_TIMER */ -- 2.30.2