X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Fx86%2Flib%2Ftsc_timer.c;h=7f5ba2ca6f1dd69f2d461723fec4536fc92a4523;hb=ba4575626eddef71b5a8dc26dc4b267918b9438c;hp=ceff60c40e6c98e50fcce23a5b7c1c22e7a2140c;hpb=80de049561f4d560c50341562b7e93ff45a1d8a0;p=oweals%2Fu-boot.git diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c index ceff60c40e..7f5ba2ca6f 100644 --- a/arch/x86/lib/tsc_timer.c +++ b/arch/x86/lib/tsc_timer.c @@ -36,7 +36,8 @@ DECLARE_GLOBAL_DATA_PTR; struct freq_desc { u8 x86_family; /* CPU family */ u8 x86_model; /* model */ - u8 msr_plat; /* 1: use MSR_PLATFORM_INFO, 0: MSR_IA32_PERF_STATUS */ + /* 2: use 100MHz, 1: use MSR_PLATFORM_INFO, 0: MSR_IA32_PERF_STATUS */ + u8 msr_plat; u32 freqs[MAX_NUM_FREQS]; }; @@ -49,6 +50,8 @@ static struct freq_desc freq_desc_tables[] = { { 6, 0x4a, 1, { 0, FREQ_100, FREQ_133, 0, 0, 0, 0, 0 } }, /* VLV2 */ { 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } }, + /* Ivybridge */ + { 6, 0x3a, 2, { 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ANN */ { 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } }, }; @@ -75,7 +78,7 @@ static int match_cpu(u8 family, u8 model) * * Returns the calibration value or 0 if MSR calibration failed. */ -static unsigned long try_msr_calibrate_tsc(void) +static unsigned long __maybe_unused try_msr_calibrate_tsc(void) { u32 lo, hi, ratio, freq_id, freq; unsigned long res; @@ -97,11 +100,18 @@ static unsigned long try_msr_calibrate_tsc(void) if (!ratio) goto fail; - /* Get FSB FREQ ID */ - rdmsr(MSR_FSB_FREQ, lo, hi); - freq_id = lo & 0x7; - freq = id_to_freq(cpu_index, freq_id); - debug("Resolved frequency ID: %u, frequency: %u KHz\n", freq_id, freq); + if (freq_desc_tables[cpu_index].msr_plat == 2) { + /* TODO: Figure out how best to deal with this */ + freq = FREQ_100; + debug("Using frequency: %u KHz\n", freq); + } else { + /* Get FSB FREQ ID */ + rdmsr(MSR_FSB_FREQ, lo, hi); + freq_id = lo & 0x7; + freq = id_to_freq(cpu_index, freq_id); + debug("Resolved frequency ID: %u, frequency: %u KHz\n", + freq_id, freq); + } if (!freq) goto fail; @@ -189,7 +199,7 @@ static inline int pit_expect_msb(unsigned char val, u64 *tscp, #define MAX_QUICK_PIT_MS 50 #define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) -static unsigned long quick_pit_calibrate(void) +static unsigned long __maybe_unused quick_pit_calibrate(void) { int i; u64 tsc, delta; @@ -293,14 +303,22 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void) { unsigned long fast_calibrate; + if (gd->arch.tsc_mhz) + return gd->arch.tsc_mhz; + +#ifdef CONFIG_TSC_CALIBRATION_BYPASS + fast_calibrate = CONFIG_TSC_FREQ_IN_MHZ; +#else fast_calibrate = try_msr_calibrate_tsc(); - if (fast_calibrate) - return fast_calibrate; + if (!fast_calibrate) { - fast_calibrate = quick_pit_calibrate(); - if (!fast_calibrate) - panic("TSC frequency is ZERO"); + fast_calibrate = quick_pit_calibrate(); + if (!fast_calibrate) + panic("TSC frequency is ZERO"); + } +#endif + gd->arch.tsc_mhz = fast_calibrate; return fast_calibrate; }