soc/amd/stoneyridge: remove dependence on TSC

The TSC rate is empirically swinging during early boot. That
leaves timestamps and udelay()s to not be correct. To rectify this
stop using TSC for all of these time sources. Instead use the
performance TSC which is at a fixed 100MHz clock. That provides
stable time sources and legit timestamps.

BUG=b:72378235,b:72170796

Change-Id: Ia2693c415c557aac687bcb48ee69358ea1c53d67
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/23424
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
Aaron Durbin 2018-01-24 17:42:51 -07:00
parent f49ddb67de
commit 51e4c1a76c
3 changed files with 12 additions and 4 deletions

View File

@ -32,14 +32,14 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
select ACPI_AMD_HARDWARE_SLEEP_VALUES
select COLLECT_TIMESTAMPS_NO_TSC
select DRIVERS_I2C_DESIGNWARE
select GENERIC_GPIO_LIB
select GENERIC_UDELAY
select IOAPIC
select HAVE_USBDEBUG_OPTIONS
select HAVE_HARD_RESET
select UDELAY_TSC
select HAVE_MONOTONIC_TIMER
select TSC_CONSTANT_RATE
select SPI_FLASH if HAVE_ACPI_RESUME
select TSC_SYNC_LFENCE
select COLLECT_TIMESTAMPS

View File

@ -28,6 +28,7 @@
#include <soc/northbridge.h>
#include <soc/southbridge.h>
#include <amdblocks/psp.h>
#include <timestamp.h>
asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
{
@ -40,7 +41,8 @@ asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
if (!boot_cpu())
bootblock_soc_early_init(); /* APs will not return */
bootblock_main_with_timestamp(base_timestamp);
/* TSC cannot be relied upon. Override the TSC value passed in. */
bootblock_main_with_timestamp(timestamp_get());
}
/* Set the MMIO Configuration Base Address and Bus Range. */

View File

@ -15,11 +15,17 @@
#include <cpu/x86/msr.h>
#include <timer.h>
#include <timestamp.h>
#define CU_PTSC_MSR 0xc0010280
#define PTSC_FREQ_MHZ 100
void timer_monotonic_get(struct mono_time *mt)
{
mono_time_set_usecs(mt, timestamp_get());
}
uint64_t timestamp_get(void)
{
unsigned long long val;
msr_t msr;
@ -28,5 +34,5 @@ void timer_monotonic_get(struct mono_time *mt)
val = ((unsigned long long)msr.hi << 32) | msr.lo;
mono_time_set_usecs(mt, val / PTSC_FREQ_MHZ);
return val / PTSC_FREQ_MHZ;
}