[CPUFREQ] p4-clockmod: add more CPUs
authorDominik Brodowski <linux@dominikbrodowski.net>
Tue, 31 Oct 2006 17:44:08 +0000 (12:44 -0500)
committerDave Jones <davej@redhat.com>
Tue, 7 Nov 2006 00:17:40 +0000 (19:17 -0500)
Several more Intel CPUs are now capable using the p4-clockmod cpufreq
driver. As it is of limited use most of the time, print a big bold warning
if a better cpufreq driver might be available.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Dave Jones <davej@redhat.com>
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
include/asm-i386/msr.h

index 304d2eaa4a1b87aeb074d7aceb181a62ba659464..bec50170b75a46816ac7b679aaac67b3a0abd7be 100644 (file)
@@ -163,29 +163,27 @@ static int cpufreq_p4_verify(struct cpufreq_policy *policy)
 
 static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
 {
-       if ((c->x86 == 0x06) && (c->x86_model == 0x09)) {
-               /* Pentium M (Banias) */
-               printk(KERN_WARNING PFX "Warning: Pentium M detected. "
-                      "The speedstep_centrino module offers voltage scaling"
-                      " in addition of frequency scaling. You should use "
-                      "that instead of p4-clockmod, if possible.\n");
-               return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
-       }
-
-       if ((c->x86 == 0x06) && (c->x86_model == 0x0D)) {
-               /* Pentium M (Dothan) */
-               printk(KERN_WARNING PFX "Warning: Pentium M detected. "
-                      "The speedstep_centrino module offers voltage scaling"
-                      " in addition of frequency scaling. You should use "
-                      "that instead of p4-clockmod, if possible.\n");
-               /* on P-4s, the TSC runs with constant frequency independent whether
-                * throttling is active or not. */
-               p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
-               return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
+       if (c->x86 == 0x06) {
+               if (cpu_has(c, X86_FEATURE_EST))
+                       printk(KERN_WARNING PFX "Warning: EST-capable CPU detected. "
+                              "The acpi-cpufreq module offers voltage scaling"
+                              " in addition of frequency scaling. You should use "
+                              "that instead of p4-clockmod, if possible.\n");
+               switch (c->x86_model) {
+               case 0x0E: /* Core */
+               case 0x0F: /* Core Duo */
+                       p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+                       return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PCORE);
+               case 0x0D: /* Pentium M (Dothan) */
+                       p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+                       /* fall through */
+               case 0x09: /* Pentium M (Banias) */
+                       return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
+               }
        }
 
        if (c->x86 != 0xF) {
-               printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. Please send an e-mail to <linux@brodo.de>\n");
+               printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. Please send an e-mail to <cpufreq@lists.linux.org.uk>\n");
                return 0;
        }
 
index 4f46cac155c4e23bff78b6762b88cd7e27fa71a0..6623a564f6fdcea6543cf7248bf97170fbb1ec7b 100644 (file)
@@ -123,6 +123,36 @@ static unsigned int pentiumM_get_frequency(void)
        return (msr_tmp * 100 * 1000);
 }
 
+static unsigned int pentium_core_get_frequency(void)
+{
+       u32 fsb = 0;
+       u32 msr_lo, msr_tmp;
+
+       rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
+       /* see table B-2 of 24547212.pdf */
+       switch (msr_lo & 0x07) {
+       case 5:
+               fsb = 400;
+               break;
+       case 1:
+               fsb = 533;
+               break;
+       case 3:
+               fsb = 667;
+               break;
+       default:
+               printk(KERN_ERR "PCORE - MSR_FSB_FREQ undefined value");
+       }
+
+       rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
+       dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
+
+       msr_tmp = (msr_lo >> 22) & 0x1f;
+       dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * fsb * 1000));
+
+       return (msr_tmp * fsb * 1000);
+}
+
 
 static unsigned int pentium4_get_frequency(void)
 {
@@ -174,6 +204,8 @@ static unsigned int pentium4_get_frequency(void)
 unsigned int speedstep_get_processor_frequency(unsigned int processor)
 {
        switch (processor) {
+       case SPEEDSTEP_PROCESSOR_PCORE:
+               return pentium_core_get_frequency();
        case SPEEDSTEP_PROCESSOR_PM:
                return pentiumM_get_frequency();
        case SPEEDSTEP_PROCESSOR_P4D:
index b735429c50b460c6dcbf9cc1790fc2ab7eab28b5..b11bcc608cac5cbe4b823ba8c3675e48932f560c 100644 (file)
@@ -22,6 +22,7 @@
  * the speedstep_get_processor_frequency() call. */
 #define SPEEDSTEP_PROCESSOR_PM                 0xFFFFFF03  /* Pentium M  */
 #define SPEEDSTEP_PROCESSOR_P4D                        0xFFFFFF04  /* desktop P4  */
+#define SPEEDSTEP_PROCESSOR_PCORE              0xFFFFFF05  /* Core */
 
 /* speedstep states -- only two of them */
 
index 0aa15fc8d918e94f9f66494ddf1c2e31f3a1dfe7..8c31887e1cfa4d5eaf2f84be8fe305a4ba64d964 100644 (file)
@@ -95,6 +95,8 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val)
 
 #define MSR_P6_PERFCTR0                0xc1
 #define MSR_P6_PERFCTR1                0xc2
+#define MSR_FSB_FREQ           0xcd
+
 
 #define MSR_IA32_BBL_CR_CTL            0x119