]> git.hungrycats.org Git - linux/commitdiff
[CPUFREQ] on P4s no TSC adjustment is necessary
authorDave Jones <davej@redhat.com>
Mon, 5 Jan 2004 18:16:28 +0000 (18:16 +0000)
committerDave Jones <davej@delerium.codemonkey.org.uk>
Mon, 5 Jan 2004 18:16:28 +0000 (18:16 +0000)
From Dominik Brodowski

arch/i386/kernel/timers/timer_tsc.c

index be9a2a533dd1e0dfad25032dc2833147fdfff386..3b081f1b82054a8aaed4d911bc07f215249c6119 100644 (file)
@@ -306,9 +306,17 @@ static void mark_offset_tsc_hpet(void)
 }
 #endif
 
+
 #ifdef CONFIG_CPU_FREQ
+/* If the CPU frequency is scaled, TSC-based delays will need a different
+ * loops_per_jiffy value to function properly. An exception to this
+ * are modern Intel Pentium 4 processors, where the TSC runs at a constant
+ * speed independent of frequency scaling. 
+ */
+
 static unsigned int  ref_freq = 0;
 static unsigned long loops_per_jiffy_ref = 0;
+static unsigned int  variable_tsc = 1;
 
 #ifndef CONFIG_SMP
 static unsigned long fast_gettimeoffset_ref = 0;
@@ -333,12 +341,15 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
 
        if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
            (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
-               cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
+               if (variable_tsc)
+                       cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
 #ifndef CONFIG_SMP
                if (use_tsc) {
-                       fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
                        cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
-                       set_cyc2ns_scale(cpu_khz/1000);
+                       if (variable_tsc) {
+                               fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
+                               set_cyc2ns_scale(cpu_khz/1000);
+                       }
                }
 #endif
        }
@@ -350,7 +361,19 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
 static struct notifier_block time_cpufreq_notifier_block = {
        .notifier_call  = time_cpufreq_notifier
 };
-#endif
+
+
+static int __init cpufreq_tsc(void)
+{
+       /* P4 and above CPU TSC freq doesn't change when CPU frequency changes*/
+       if ((boot_cpu_data.x86 >= 15) && (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+               variable_tsc = 0;
+
+       return cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+}
+core_initcall(cpufreq_tsc);
+
+#endif 
 
 
 static int __init init_tsc(char* override)
@@ -392,10 +415,6 @@ static int __init init_tsc(char* override)
         *      some CPU's have a TSC. Thats never worked and nobody has
         *      moaned if you have the only one in the world - you fix it!
         */
-#ifdef CONFIG_CPU_FREQ
-       cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-#endif
 
        count2 = LATCH; /* initialize counter for mark_offset_tsc() */