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>
This commit is contained in:
@ -18,26 +18,9 @@
|
||||
#include <delay.h>
|
||||
#include <thread.h>
|
||||
|
||||
static unsigned long clocks_per_usec CAR_GLOBAL;
|
||||
|
||||
static unsigned long calibrate_tsc(void)
|
||||
{
|
||||
if (CONFIG(TSC_CONSTANT_RATE))
|
||||
return tsc_freq_mhz();
|
||||
else
|
||||
return calibrate_tsc_with_pit();
|
||||
}
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
if (!car_get_var(clocks_per_usec))
|
||||
car_set_var(clocks_per_usec, calibrate_tsc());
|
||||
}
|
||||
|
||||
static inline unsigned long get_clocks_per_usec(void)
|
||||
{
|
||||
init_timer();
|
||||
return car_get_var(clocks_per_usec);
|
||||
(void)tsc_freq_mhz();
|
||||
}
|
||||
|
||||
void udelay(unsigned int us)
|
||||
@ -51,7 +34,7 @@ void udelay(unsigned int us)
|
||||
|
||||
start = rdtscll();
|
||||
clocks = us;
|
||||
clocks *= get_clocks_per_usec();
|
||||
clocks *= tsc_freq_mhz();
|
||||
current = rdtscll();
|
||||
while ((current - start) < clocks) {
|
||||
cpu_relax();
|
||||
@ -89,7 +72,7 @@ void timer_monotonic_get(struct mono_time *mt)
|
||||
|
||||
current_tick = rdtscll();
|
||||
ticks_elapsed = current_tick - mono_counter->last_value;
|
||||
ticks_per_usec = get_clocks_per_usec();
|
||||
ticks_per_usec = tsc_freq_mhz();
|
||||
|
||||
/* Update current time and tick values only if a full tick occurred. */
|
||||
if (ticks_elapsed >= ticks_per_usec) {
|
||||
|
Reference in New Issue
Block a user