summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2019-10-31 14:52:20 +0200
committerKyösti Mälkki <kyosti.malkki@gmail.com>2019-11-03 06:15:35 +0000
commit0d6ddf8da7632e775dde92c9114ac6ace5ca5f14 (patch)
tree67b37afc2c6bc3cfaa3750a87394c5b056067137 /src/drivers
parentea2bec2c4b1a986b059147506c99a202d5c8fad3 (diff)
cpu/x86/tsc: Flip and rename TSC_CONSTANT_RATE to UNKNOWN_TSC_RATE
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 <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/33928 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/pc80/pc/i8254.c23
1 files changed, 23 insertions, 0 deletions
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 <arch/early_variables.h>
#include <arch/io.h>
#include <commonlib/helpers.h>
#include <cpu/x86/tsc.h>
@@ -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