Skip to content
Snippets Groups Projects
Commit 5c1b685e authored by Simon Glass's avatar Simon Glass
Browse files

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: default avatarSimon Glass <sjg@chromium.org>
Reviewed-by: default avatarBin Meng <bmeng.cn@gmail.com>
parent a5eb04db
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment