summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2014-11-12 22:42:04 -0700
committerSimon Glass <sjg@chromium.org>2014-11-21 07:24:12 +0100
commit5c1b685e46756dc9504b919336321dad27dbcd9e (patch)
treee4a3f61e5571d16f283863f6ca29e30f5a819a53
parenta5eb04db1a8fac8c7691c87cbbb890c8174ab906 (diff)
downloadu-boot-imx-5c1b685e46756dc9504b919336321dad27dbcd9e.zip
u-boot-imx-5c1b685e46756dc9504b919336321dad27dbcd9e.tar.gz
u-boot-imx-5c1b685e46756dc9504b919336321dad27dbcd9e.tar.bz2
x86: Allow timer calibration to work on ivybridge
Unfortunately MSR_FSB_FREQ is not available on this CPU, and the PIT method seems to take up to 50ms which is much too long. For this CPU we know the frequency, so add another special case for now. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-rw-r--r--arch/x86/lib/tsc_timer.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c
index f091c91..fb9afed 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 } },
};
@@ -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;
@@ -297,12 +307,12 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void)
return gd->arch.tsc_mhz;
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");
+ }
gd->arch.tsc_mhz = fast_calibrate;
return fast_calibrate;