aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/tsc_32.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_32.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_32.c')
-rw-r--r--arch/x86/kernel/tsc_32.c74
1 files changed, 1 insertions, 73 deletions
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index dc8990056d75..40c0aafb358d 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -42,7 +42,7 @@ extern int tsc_disabled;
42 42
43DEFINE_PER_CPU(unsigned long, cyc2ns); 43DEFINE_PER_CPU(unsigned long, cyc2ns);
44 44
45static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) 45void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
46{ 46{
47 unsigned long long tsc_now, ns_now; 47 unsigned long long tsc_now, ns_now;
48 unsigned long flags, *scale; 48 unsigned long flags, *scale;
@@ -65,78 +65,6 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
65 local_irq_restore(flags); 65 local_irq_restore(flags);
66} 66}
67 67
68unsigned long native_calculate_cpu_khz(void)
69{
70 unsigned long long start, end;
71 unsigned long count;
72 u64 delta64 = (u64)ULLONG_MAX;
73 int i;
74 unsigned long flags;
75
76 local_irq_save(flags);
77
78 /* run 3 times to ensure the cache is warm and to get an accurate reading */
79 for (i = 0; i < 3; i++) {
80 mach_prepare_counter();
81 rdtscll(start);
82 mach_countup(&count);
83 rdtscll(end);
84
85 /*
86 * Error: ECTCNEVERSET
87 * The CTC wasn't reliable: we got a hit on the very first read,
88 * or the CPU was so fast/slow that the quotient wouldn't fit in
89 * 32 bits..
90 */
91 if (count <= 1)
92 continue;
93
94 /* cpu freq too slow: */
95 if ((end - start) <= CALIBRATE_TIME_MSEC)
96 continue;
97
98 /*
99 * We want the minimum time of all runs in case one of them
100 * is inaccurate due to SMI or other delay
101 */
102 delta64 = min(delta64, (end - start));
103 }
104
105 /* cpu freq too fast (or every run was bad): */
106 if (delta64 > (1ULL<<32))
107 goto err;
108
109 delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */
110 do_div(delta64,CALIBRATE_TIME_MSEC);
111
112 local_irq_restore(flags);
113 return (unsigned long)delta64;
114err:
115 local_irq_restore(flags);
116 return 0;
117}
118
119int recalibrate_cpu_khz(void)
120{
121#ifndef CONFIG_SMP
122 unsigned long cpu_khz_old = cpu_khz;
123
124 if (cpu_has_tsc) {
125 cpu_khz = calculate_cpu_khz();
126 tsc_khz = cpu_khz;
127 cpu_data(0).loops_per_jiffy =
128 cpufreq_scale(cpu_data(0).loops_per_jiffy,
129 cpu_khz_old, cpu_khz);
130 return 0;
131 } else
132 return -ENODEV;
133#else
134 return -ENODEV;
135#endif
136}
137
138EXPORT_SYMBOL(recalibrate_cpu_khz);
139
140#ifdef CONFIG_CPU_FREQ 68#ifdef CONFIG_CPU_FREQ
141 69
142/* 70/*