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>
diff --git a/src/arch/x86/cpu.c b/src/arch/x86/cpu.c
index cfab219..30d2cca 100644
--- a/src/arch/x86/cpu.c
+++ b/src/arch/x86/cpu.c
@@ -315,7 +315,7 @@
 	struct lb_tsc_info *tsc_info;
 
 	/* Don't advertise a TSC rate unless it's constant. */
-	if (!CONFIG(TSC_CONSTANT_RATE))
+	if (!tsc_constant_rate())
 		return;
 
 	freq_khz = tsc_freq_mhz() * 1000;
diff --git a/src/arch/x86/timestamp.c b/src/arch/x86/timestamp.c
index 92d9590..8cf0f96 100644
--- a/src/arch/x86/timestamp.c
+++ b/src/arch/x86/timestamp.c
@@ -22,7 +22,7 @@
 int timestamp_tick_freq_mhz(void)
 {
 	/* Chipsets that have a constant TSC provide this value correctly. */
-	if (CONFIG(TSC_CONSTANT_RATE))
+	if (tsc_constant_rate())
 		return tsc_freq_mhz();
 
 	/* Filling tick_freq_mhz = 0 in timestamps-table will trigger
diff --git a/src/cpu/intel/fsp_model_406dx/Kconfig b/src/cpu/intel/fsp_model_406dx/Kconfig
index 77ba0bd..3e714699 100644
--- a/src/cpu/intel/fsp_model_406dx/Kconfig
+++ b/src/cpu/intel/fsp_model_406dx/Kconfig
@@ -32,7 +32,6 @@
 	select PARALLEL_CPU_INIT
 	select TSC_SYNC_MFENCE
 	select TSC_MONOTONIC_TIMER
-	select TSC_CONSTANT_RATE
 	select CPU_INTEL_COMMON
 	select CPU_INTEL_COMMON_TIMEBASE
 	select NO_SMM
diff --git a/src/cpu/intel/haswell/Kconfig b/src/cpu/intel/haswell/Kconfig
index db119a0..d8d8b97 100644
--- a/src/cpu/intel/haswell/Kconfig
+++ b/src/cpu/intel/haswell/Kconfig
@@ -14,7 +14,6 @@
 	select MMX
 	select SSE2
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select SUPPORT_CPU_UCODE_IN_CBFS
 	#select AP_IN_SIPI_WAIT
diff --git a/src/cpu/intel/model_1067x/Kconfig b/src/cpu/intel/model_1067x/Kconfig
index 16bc03b..564a428 100644
--- a/src/cpu/intel/model_1067x/Kconfig
+++ b/src/cpu/intel/model_1067x/Kconfig
@@ -7,7 +7,6 @@
 	select SMP
 	select SSE2
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select TSC_SYNC_MFENCE
 	select SUPPORT_CPU_UCODE_IN_CBFS
diff --git a/src/cpu/intel/model_106cx/Kconfig b/src/cpu/intel/model_106cx/Kconfig
index 43c4048..1ba8894 100644
--- a/src/cpu/intel/model_106cx/Kconfig
+++ b/src/cpu/intel/model_106cx/Kconfig
@@ -7,7 +7,6 @@
 	select SMP
 	select SSE2
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select SIPI_VECTOR_IN_ROM
 	select AP_IN_SIPI_WAIT
diff --git a/src/cpu/intel/model_2065x/Kconfig b/src/cpu/intel/model_2065x/Kconfig
index 5727511..a76a95d 100644
--- a/src/cpu/intel/model_2065x/Kconfig
+++ b/src/cpu/intel/model_2065x/Kconfig
@@ -12,7 +12,6 @@
 	select SMP
 	select SSE2
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select SUPPORT_CPU_UCODE_IN_CBFS
 	select PARALLEL_CPU_INIT
diff --git a/src/cpu/intel/model_206ax/Kconfig b/src/cpu/intel/model_206ax/Kconfig
index 97d8d3d..8dae6ec 100644
--- a/src/cpu/intel/model_206ax/Kconfig
+++ b/src/cpu/intel/model_206ax/Kconfig
@@ -13,7 +13,6 @@
 	select MMX
 	select SSE2
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select SUPPORT_CPU_UCODE_IN_CBFS
 	#select AP_IN_SIPI_WAIT
diff --git a/src/cpu/intel/model_6ex/Kconfig b/src/cpu/intel/model_6ex/Kconfig
index ff16724..3af5272 100644
--- a/src/cpu/intel/model_6ex/Kconfig
+++ b/src/cpu/intel/model_6ex/Kconfig
@@ -7,7 +7,6 @@
 	select SMP
 	select SSE2
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select AP_IN_SIPI_WAIT
 	select TSC_SYNC_MFENCE
diff --git a/src/cpu/intel/model_6fx/Kconfig b/src/cpu/intel/model_6fx/Kconfig
index e6c8256..cfd3e7c 100644
--- a/src/cpu/intel/model_6fx/Kconfig
+++ b/src/cpu/intel/model_6fx/Kconfig
@@ -7,7 +7,6 @@
 	select SMP
 	select SSE2
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select AP_IN_SIPI_WAIT
 	select TSC_SYNC_MFENCE
diff --git a/src/cpu/intel/slot_1/Kconfig b/src/cpu/intel/slot_1/Kconfig
index d932494..3d0522a 100644
--- a/src/cpu/intel/slot_1/Kconfig
+++ b/src/cpu/intel/slot_1/Kconfig
@@ -25,6 +25,7 @@
 	select CPU_INTEL_MODEL_6XX
 	select NO_SMM
 	select NO_MONOTONIC_TIMER
+	select UNKNOWN_TSC_RATE
 
 config DCACHE_RAM_BASE
 	hex
diff --git a/src/cpu/intel/socket_mPGA604/Kconfig b/src/cpu/intel/socket_mPGA604/Kconfig
index 4ec46e0..a2ebeb2 100644
--- a/src/cpu/intel/socket_mPGA604/Kconfig
+++ b/src/cpu/intel/socket_mPGA604/Kconfig
@@ -9,7 +9,6 @@
 	select MMX
 	select SSE
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select SIPI_VECTOR_IN_ROM
 	select C_ENVIRONMENT_BOOTBLOCK
diff --git a/src/cpu/qemu-x86/Kconfig b/src/cpu/qemu-x86/Kconfig
index a6c9b74..7504233 100644
--- a/src/cpu/qemu-x86/Kconfig
+++ b/src/cpu/qemu-x86/Kconfig
@@ -20,5 +20,6 @@
 	select SMP
 	select UDELAY_TSC
 	select TSC_MONOTONIC_TIMER
+	select UNKNOWN_TSC_RATE
 	select C_ENVIRONMENT_BOOTBLOCK
 	select SMM_ASEG
diff --git a/src/cpu/via/nano/Kconfig b/src/cpu/via/nano/Kconfig
index 4b96c7c..14acfd5 100644
--- a/src/cpu/via/nano/Kconfig
+++ b/src/cpu/via/nano/Kconfig
@@ -25,6 +25,7 @@
 	select ARCH_RAMSTAGE_X86_32
 	select UDELAY_TSC
 	select TSC_MONOTONIC_TIMER
+	select UNKNOWN_TSC_RATE
 	select MMX
 	select SSE2
 	select SUPPORT_CPU_UCODE_IN_CBFS
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index b316c1f..85ebd83 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -34,12 +34,9 @@
 	bool
 	default n
 
-config TSC_CONSTANT_RATE
-	def_bool n
-	depends on UDELAY_TSC
-	help
-	  This option asserts that the TSC ticks at a known constant rate.
-	  Therefore, no TSC calibration is required.
+config UNKNOWN_TSC_RATE
+	bool
+	default y if LAPIC_MONOTONIC_TIMER
 
 config TSC_MONOTONIC_TIMER
 	def_bool n
diff --git a/src/cpu/x86/tsc/Makefile.inc b/src/cpu/x86/tsc/Makefile.inc
index ab7453f..b3925b5 100644
--- a/src/cpu/x86/tsc/Makefile.inc
+++ b/src/cpu/x86/tsc/Makefile.inc
@@ -1,6 +1,6 @@
 bootblock-$(CONFIG_UDELAY_TSC) += delay_tsc.c
 ramstage-$(CONFIG_UDELAY_TSC) += delay_tsc.c
-romstage-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
-verstage-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
-postcar-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
-smm-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
+romstage-$(CONFIG_UDELAY_TSC) += delay_tsc.c
+verstage-$(CONFIG_UDELAY_TSC) += delay_tsc.c
+postcar-$(CONFIG_UDELAY_TSC) += delay_tsc.c
+smm-$(CONFIG_UDELAY_TSC) += delay_tsc.c
diff --git a/src/cpu/x86/tsc/delay_tsc.c b/src/cpu/x86/tsc/delay_tsc.c
index afcd1d1..7aa887a 100644
--- a/src/cpu/x86/tsc/delay_tsc.c
+++ b/src/cpu/x86/tsc/delay_tsc.c
@@ -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 @@
 
 	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 @@
 
 	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) {
diff --git a/src/drivers/pc80/pc/i8254.c b/src/drivers/pc80/pc/i8254.c
index 8e15d4d..654f84a 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 @@
 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
diff --git a/src/include/cpu/x86/tsc.h b/src/include/cpu/x86/tsc.h
index dd333e8..c18f878 100644
--- a/src/include/cpu/x86/tsc.h
+++ b/src/include/cpu/x86/tsc.h
@@ -63,4 +63,9 @@
 /* Provided by CPU/chipset code for the TSC rate in MHz. */
 unsigned long tsc_freq_mhz(void);
 
+static inline int tsc_constant_rate(void)
+{
+	return !CONFIG(UNKNOWN_TSC_RATE);
+}
+
 #endif /* CPU_X86_TSC_H */
diff --git a/src/northbridge/via/vx900/Makefile.inc b/src/northbridge/via/vx900/Makefile.inc
index bbfe63b..247cc24 100644
--- a/src/northbridge/via/vx900/Makefile.inc
+++ b/src/northbridge/via/vx900/Makefile.inc
@@ -28,7 +28,6 @@
 romstage-y += ./../../../southbridge/via/common/early_smbus_print_error.c
 romstage-y += ./../../../southbridge/via/common/early_smbus_reset.c
 romstage-y += ./../../../southbridge/via/common/early_smbus_wait_until_ready.c
-romstage-y += ./../../../drivers/pc80/pc/udelay_io.c
 
 ramstage-y += pci_util.c
 ramstage-y += pcie.c
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig
index d87d634..5f9792b 100644
--- a/src/soc/amd/picasso/Kconfig
+++ b/src/soc/amd/picasso/Kconfig
@@ -33,7 +33,6 @@
 	select GENERIC_GPIO_LIB
 	select IOAPIC
 	select HAVE_USBDEBUG_OPTIONS
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select SOC_AMD_COMMON_BLOCK_SPI
 	select TSC_SYNC_LFENCE
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig
index b54528f..026f6da 100644
--- a/src/soc/intel/apollolake/Kconfig
+++ b/src/soc/intel/apollolake/Kconfig
@@ -95,7 +95,6 @@
 	select SOC_INTEL_COMMON_BLOCK_SPI
 	select SOC_INTEL_COMMON_BLOCK_CSE
 	select UDELAY_TSC
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select PLATFORM_USES_FSP2_0
 	select UDK_2015_BINDING if !SOC_INTEL_GLK
diff --git a/src/soc/intel/baytrail/Kconfig b/src/soc/intel/baytrail/Kconfig
index c833c53..397e867 100644
--- a/src/soc/intel/baytrail/Kconfig
+++ b/src/soc/intel/baytrail/Kconfig
@@ -27,7 +27,6 @@
 	select SMP
 	select SPI_FLASH
 	select SSE2
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select TSC_SYNC_MFENCE
 	select UDELAY_TSC
diff --git a/src/soc/intel/braswell/Kconfig b/src/soc/intel/braswell/Kconfig
index 5053790..7ea0186 100644
--- a/src/soc/intel/braswell/Kconfig
+++ b/src/soc/intel/braswell/Kconfig
@@ -34,7 +34,6 @@
 	select SMP
 	select SPI_FLASH
 	select SSE2
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select TSC_SYNC_MFENCE
 	select UDELAY_TSC
diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig
index 5856ef1..fadbb41 100644
--- a/src/soc/intel/broadwell/Kconfig
+++ b/src/soc/intel/broadwell/Kconfig
@@ -27,7 +27,6 @@
 	select SMP
 	select SPI_FLASH
 	select SSE2
-	select TSC_CONSTANT_RATE
 	select TSC_SYNC_MFENCE
 	select UDELAY_TSC
 	select SOC_INTEL_COMMON
diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig
index 941c150..3330a69 100644
--- a/src/soc/intel/cannonlake/Kconfig
+++ b/src/soc/intel/cannonlake/Kconfig
@@ -102,7 +102,6 @@
 	select SOC_INTEL_COMMON_RESET
 	select SSE2
 	select SUPPORT_CPU_UCODE_IN_CBFS
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select UDELAY_TSC
 	select UDK_2017_BINDING
diff --git a/src/soc/intel/denverton_ns/Kconfig b/src/soc/intel/denverton_ns/Kconfig
index 2aadcae..cb3713d 100644
--- a/src/soc/intel/denverton_ns/Kconfig
+++ b/src/soc/intel/denverton_ns/Kconfig
@@ -50,7 +50,6 @@
 	select SOC_INTEL_COMMON_BLOCK_FAST_SPI
 	select SOC_INTEL_COMMON_BLOCK_GPIO
 	select SOC_INTEL_COMMON_BLOCK_PCR
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select TSC_SYNC_MFENCE
 	select UDELAY_TSC
diff --git a/src/soc/intel/fsp_baytrail/Kconfig b/src/soc/intel/fsp_baytrail/Kconfig
index efe12da..5a8bec9 100644
--- a/src/soc/intel/fsp_baytrail/Kconfig
+++ b/src/soc/intel/fsp_baytrail/Kconfig
@@ -36,7 +36,6 @@
 	select SMP
 	select SPI_FLASH
 	select SSE2
-	select TSC_CONSTANT_RATE
 	select TSC_SYNC_MFENCE
 	select UDELAY_TSC
 	select TSC_MONOTONIC_TIMER
diff --git a/src/soc/intel/fsp_broadwell_de/Kconfig b/src/soc/intel/fsp_broadwell_de/Kconfig
index 6c74a74..4c50828 100644
--- a/src/soc/intel/fsp_broadwell_de/Kconfig
+++ b/src/soc/intel/fsp_broadwell_de/Kconfig
@@ -24,7 +24,6 @@
 	select INTEL_DESCRIPTOR_MODE_CAPABLE
 	select HAVE_SMI_HANDLER
 	select TSC_MONOTONIC_TIMER
-	select TSC_CONSTANT_RATE
 	select HAVE_FSP_BIN
 	select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
 	select SOC_INTEL_COMMON
diff --git a/src/soc/intel/icelake/Kconfig b/src/soc/intel/icelake/Kconfig
index 993e9b2..86f1ff5 100644
--- a/src/soc/intel/icelake/Kconfig
+++ b/src/soc/intel/icelake/Kconfig
@@ -53,7 +53,6 @@
 	select SOC_INTEL_COMMON_RESET
 	select SSE2
 	select SUPPORT_CPU_UCODE_IN_CBFS
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select UDELAY_TSC
 	select UDK_2017_BINDING
diff --git a/src/soc/intel/quark/Kconfig b/src/soc/intel/quark/Kconfig
index b752784..75f1354 100644
--- a/src/soc/intel/quark/Kconfig
+++ b/src/soc/intel/quark/Kconfig
@@ -34,7 +34,6 @@
 	select SOC_INTEL_COMMON_RESET
 	select SOC_SETS_MSRS
 	select SPI_FLASH
-	select TSC_CONSTANT_RATE
 	select UART_OVERRIDE_REFCLK
 	select UDELAY_TSC
 	select UNCOMPRESSED_RAMSTAGE
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index f9f6f93..d4720a2 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -76,7 +76,6 @@
 	select SOC_INTEL_COMMON_RESET
 	select SSE2
 	select SUPPORT_CPU_UCODE_IN_CBFS
-	select TSC_CONSTANT_RATE
 	select TSC_MONOTONIC_TIMER
 	select TSC_SYNC_MFENCE
 	select UDELAY_TSC