From 0d6ddf8da7632e775dde92c9114ac6ace5ca5f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 31 Oct 2019 14:52:20 +0200 Subject: cpu/x86/tsc: Flip and rename TSC_CONSTANT_RATE to UNKNOWN_TSC_RATE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The x86 timers are a bit of a mess. Cases where different stages use different counters and timestamps use different counters from udelays. The original intention was to only flip TSC_CONSTANT_RATE Kconfig to NOT_CONSTANT_TSC_RATE. The name would be incorrect though, those counters do run with a constant rate but we just lack tsc_freq_mhz() implementation for three platforms. Note that for boards with UNKNOWN_TSC_RATE=y, each stage will have a slow run of calibrate_tsc_with_pit(). This is easy enough to fix with followup implementation of tsc_freq_mhz() for the platforms. Implementations with LAPIC_MONOTONIC_TIMER typically will not have tsc_freq_mhz() implemented and default to UNKNOWN_TSC_RATE. However, as they don't use TSC for udelay() the slow calibrate_tsc_with_pit() is avoided. Because x86/tsc_delay.tsc was using two different guards and nb/via/vx900 claimed UDELAY_TSC, but pulled UDELAY_IO implementation, we also switch that romstage to use UDELAY_TSC. Change-Id: I1690cb80295d6b006b75ed69edea28899b674b68 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/33928 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/drivers/pc80/pc/i8254.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/drivers') diff --git a/src/drivers/pc80/pc/i8254.c b/src/drivers/pc80/pc/i8254.c index 8e15d4ded1..654f84a6d7 100644 --- a/src/drivers/pc80/pc/i8254.c +++ b/src/drivers/pc80/pc/i8254.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -122,3 +123,25 @@ unsigned long calibrate_tsc_with_pit(void) bad_ctc: return 0; } + +#if CONFIG(UNKNOWN_TSC_RATE) +static u32 g_timer_tsc CAR_GLOBAL; + +unsigned long tsc_freq_mhz(void) +{ + u32 tsc; + + tsc = car_get_var(g_timer_tsc); + if (tsc > 0) + return tsc; + + tsc = calibrate_tsc_with_pit(); + + /* Set some semi-ridiculous rate if approximation fails. */ + if (tsc == 0) + tsc = 5000; + + car_set_var(g_timer_tsc, tsc); + return tsc; +} +#endif -- cgit v1.2.3