aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/tsc_64.c
diff options
context:
space:
mode:
authorAlok Kataria <akataria@vmware.com>2008-07-01 14:43:24 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-09 01:43:25 -0400
commitbfc0f5947afa5e3a13e55867f4478c8a92c11dca (patch)
treebb642adee69c7804eaafbb7fad66af61b4f9f56f /arch/x86/kernel/tsc_64.c
parent0ef95533326a7b37d16025af9edc0c18e644b346 (diff)
x86: merge tsc calibration
Merge the tsc calibration code for the 32bit and 64bit kernel. The paravirtualized calculate_cpu_khz for 64bit now points to the correct tsc_calibrate code as in 32bit. Original native_calculate_cpu_khz for 64 bit is now called as calibrate_cpu. Also moved the recalibrate_cpu_khz function in the common file. Note that this function is called only from powernow K7 cpu freq driver. Signed-off-by: Alok N Kataria <akataria@vmware.com> Signed-off-by: Dan Hecht <dhecht@vmware.com> Cc: Dan Hecht <dhecht@vmware.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/tsc_64.c')
-rw-r--r--arch/x86/kernel/tsc_64.c94
1 files changed, 1 insertions, 93 deletions
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index 69cbe4c9f050..c852ff9bd5d4 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -40,7 +40,7 @@ extern int tsc_disabled;
40 40
41DEFINE_PER_CPU(unsigned long, cyc2ns); 41DEFINE_PER_CPU(unsigned long, cyc2ns);
42 42
43static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) 43void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
44{ 44{
45 unsigned long long tsc_now, ns_now; 45 unsigned long long tsc_now, ns_now;
46 unsigned long flags, *scale; 46 unsigned long flags, *scale;
@@ -130,98 +130,6 @@ core_initcall(cpufreq_tsc);
130 130
131#endif 131#endif
132 132
133#define MAX_RETRIES 5
134#define SMI_TRESHOLD 50000
135
136/*
137 * Read TSC and the reference counters. Take care of SMI disturbance
138 */
139static unsigned long __init tsc_read_refs(unsigned long *pm,
140 unsigned long *hpet)
141{
142 unsigned long t1, t2;
143 int i;
144
145 for (i = 0; i < MAX_RETRIES; i++) {
146 t1 = get_cycles();
147 if (hpet)
148 *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
149 else
150 *pm = acpi_pm_read_early();
151 t2 = get_cycles();
152 if ((t2 - t1) < SMI_TRESHOLD)
153 return t2;
154 }
155 return ULONG_MAX;
156}
157
158/**
159 * tsc_calibrate - calibrate the tsc on boot
160 */
161void __init tsc_calibrate(void)
162{
163 unsigned long flags, tsc1, tsc2, tr1, tr2, pm1, pm2, hpet1, hpet2;
164 int hpet = is_hpet_enabled(), cpu;
165
166 local_irq_save(flags);
167
168 tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
169
170 outb((inb(0x61) & ~0x02) | 0x01, 0x61);
171
172 outb(0xb0, 0x43);
173 outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
174 outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
175 tr1 = get_cycles();
176 while ((inb(0x61) & 0x20) == 0);
177 tr2 = get_cycles();
178
179 tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
180
181 local_irq_restore(flags);
182
183 /*
184 * Preset the result with the raw and inaccurate PIT
185 * calibration value
186 */
187 tsc_khz = (tr2 - tr1) / 50;
188
189 /* hpet or pmtimer available ? */
190 if (!hpet && !pm1 && !pm2) {
191 printk(KERN_INFO "TSC calibrated against PIT\n");
192 goto out;
193 }
194
195 /* Check, whether the sampling was disturbed by an SMI */
196 if (tsc1 == ULONG_MAX || tsc2 == ULONG_MAX) {
197 printk(KERN_WARNING "TSC calibration disturbed by SMI, "
198 "using PIT calibration result\n");
199 goto out;
200 }
201
202 tsc2 = (tsc2 - tsc1) * 1000000L;
203
204 if (hpet) {
205 printk(KERN_INFO "TSC calibrated against HPET\n");
206 if (hpet2 < hpet1)
207 hpet2 += 0x100000000UL;
208 hpet2 -= hpet1;
209 tsc1 = (hpet2 * hpet_readl(HPET_PERIOD)) / 1000000;
210 } else {
211 printk(KERN_INFO "TSC calibrated against PM_TIMER\n");
212 if (pm2 < pm1)
213 pm2 += ACPI_PM_OVRRUN;
214 pm2 -= pm1;
215 tsc1 = (pm2 * 1000000000) / PMTMR_TICKS_PER_SEC;
216 }
217
218 tsc_khz = tsc2 / tsc1;
219
220out:
221 for_each_possible_cpu(cpu)
222 set_cyc2ns_scale(tsc_khz, cpu);
223}
224
225/* 133/*
226 * Make an educated guess if the TSC is trustworthy and synchronized 134 * Make an educated guess if the TSC is trustworthy and synchronized
227 * over all CPUs. 135 * over all CPUs.