aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/tsc.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index aa11413e7c1d..ebb9bf824a07 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -122,6 +122,43 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
122 return ULLONG_MAX; 122 return ULLONG_MAX;
123} 123}
124 124
125/*
126 * Calculate the TSC frequency from HPET reference
127 */
128static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2)
129{
130 u64 tmp;
131
132 if (hpet2 < hpet1)
133 hpet2 += 0x100000000ULL;
134 hpet2 -= hpet1;
135 tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
136 do_div(tmp, 1000000);
137 do_div(deltatsc, tmp);
138
139 return (unsigned long) deltatsc;
140}
141
142/*
143 * Calculate the TSC frequency from PMTimer reference
144 */
145static unsigned long calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2)
146{
147 u64 tmp;
148
149 if (!pm1 && !pm2)
150 return ULONG_MAX;
151
152 if (pm2 < pm1)
153 pm2 += (u64)ACPI_PM_OVRRUN;
154 pm2 -= pm1;
155 tmp = pm2 * 1000000000LL;
156 do_div(tmp, PMTMR_TICKS_PER_SEC);
157 do_div(deltatsc, tmp);
158
159 return (unsigned long) deltatsc;
160}
161
125#define CAL_MS 50 162#define CAL_MS 50
126#define CAL_LATCH (CLOCK_TICK_RATE / (1000 / CAL_MS)) 163#define CAL_LATCH (CLOCK_TICK_RATE / (1000 / CAL_MS))
127#define CAL_PIT_LOOPS 5000 164#define CAL_PIT_LOOPS 5000
@@ -247,22 +284,11 @@ unsigned long native_calibrate_tsc(void)
247 continue; 284 continue;
248 285
249 tsc2 = (tsc2 - tsc1) * 1000000LL; 286 tsc2 = (tsc2 - tsc1) * 1000000LL;
287 if (hpet)
288 tsc2 = calc_hpet_ref(tsc2, hpet1, hpet2);
289 else
290 tsc2 = calc_pmtimer_ref(tsc2, pm1, pm2);
250 291
251 if (hpet) {
252 if (hpet2 < hpet1)
253 hpet2 += 0x100000000ULL;
254 hpet2 -= hpet1;
255 tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
256 do_div(tsc1, 1000000);
257 } else {
258 if (pm2 < pm1)
259 pm2 += (u64)ACPI_PM_OVRRUN;
260 pm2 -= pm1;
261 tsc1 = pm2 * 1000000000LL;
262 do_div(tsc1, PMTMR_TICKS_PER_SEC);
263 }
264
265 do_div(tsc2, tsc1);
266 tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2); 292 tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2);
267 } 293 }
268 294