dm: x86: spi: Convert ICH SPI driver to driver model
[oweals/u-boot.git] / arch / x86 / lib / tsc_timer.c
index ceff60c40e6c98e50fcce23a5b7c1c22e7a2140c..7f5ba2ca6f1dd69f2d461723fec4536fc92a4523 100644 (file)
@@ -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;
 }