]> git.hungrycats.org Git - linux/commitdiff
[CPUFREQ] Nehemiah improvements for longhaul driver.
authorDave Jones <davej@redhat.com>
Tue, 11 May 2004 14:01:27 +0000 (15:01 +0100)
committerDave Jones <davej@delerium.codemonkey.org.uk>
Tue, 11 May 2004 14:01:27 +0000 (15:01 +0100)
From Andreas Meisinger

arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/longhaul.h

index a94917bc2be391461111615c2364194375c212f6..5510cd6a28f62114a9c781999196459b7b2996e6 100644 (file)
@@ -82,6 +82,10 @@ static int longhaul_get_cpu_mult (void)
                if (lo & (1<<27))
                        invalue+=16;
        }
+       if (longhaul_version==4) {
+               if (lo & (1<<27))
+                       invalue+=16;
+       }
        return eblcr_table[invalue];
 }
 
@@ -158,6 +162,22 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
                longhaul.bits.RevisionKey = 3;
                wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
                break;
+       case 4:
+               rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
+               longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
+               longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
+               longhaul.bits.EnableSoftBusRatio = 1;
+               
+               longhaul.bits.RevisionKey = 0x0;
+               
+               wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+               __hlt();
+               
+               rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
+               longhaul.bits.EnableSoftBusRatio = 0;
+               longhaul.bits.RevisionKey = 0xf;
+               wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);                
+               break;
        }
 
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
@@ -207,7 +227,7 @@ static int guess_fsb(int maxmult)
 static int __init longhaul_get_ranges (void)
 {
        struct cpuinfo_x86 *c = cpu_data;
-       unsigned long invalue;
+       unsigned long invalue,invalue2;
        unsigned int minmult=0, maxmult=0;
        unsigned int multipliers[32]= {
                50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
@@ -234,8 +254,6 @@ static int __init longhaul_get_ranges (void)
        case 2:
                rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
 
-               //TODO: Nehemiah may have borken MaxMHzBR.
-               // need to extrapolate from FSB.
                invalue = longhaul.bits.MaxMHzBR;
                if (longhaul.bits.MaxMHzBR4)
                        invalue += 16;
@@ -258,6 +276,38 @@ static int __init longhaul_get_ranges (void)
                                break;
                }
                break;
+               
+       case 4:
+               rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
+               
+               //TODO: Nehemiah may have borken MaxMHzBR.
+               // need to extrapolate from FSB.
+               
+               invalue2 = longhaul.bits.MinMHzBR;
+               invalue = longhaul.bits.MaxMHzBR;
+               if (longhaul.bits.MaxMHzBR4) 
+                       invalue += 16;
+               maxmult=multipliers[invalue];
+               
+               maxmult=longhaul_get_cpu_mult();
+               
+               printk(KERN_INFO PFX " invalue: %ld  maxmult: %d \n", invalue, maxmult);
+               printk(KERN_INFO PFX " invalue2: %ld \n", invalue2);
+               
+               minmult=50;
+               
+               switch (longhaul.bits.MaxMHzFSB) {
+               case 0x0:       fsb=133;
+                               break;
+               case 0x1:       fsb=100;
+                               break;
+               case 0x2:       printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
+                       return -EINVAL;
+               case 0x3:       fsb=66;
+                               break;
+               }
+               
+               break;  
        }
 
        dprintk (KERN_INFO PFX "MinMult=%d.%dx MaxMult=%d.%dx\n",
@@ -430,12 +480,27 @@ static int __init longhaul_cpu_init (struct cpufreq_policy *policy)
                break;
 
        case 9:
-               cpuname = "C3 'Nehemiah' [C5N]";
-               longhaul_version=2;
+               longhaul_version=4;
                numscales=32;
-               memcpy (clock_ratio, nehemiah_clock_ratio, sizeof(nehemiah_clock_ratio));
-               memcpy (eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr));
+               switch (c->x86_mask) {
+               case 0 ... 1:
+                       cpuname = "C3 'Nehemiah A' [C5N]";
+                       memcpy (clock_ratio, nehemiah_a_clock_ratio, sizeof(nehemiah_a_clock_ratio));
+                       memcpy (eblcr_table, nehemiah_a_eblcr, sizeof(nehemiah_a_eblcr));
+                       break;
+               case 2 ... 4:
+                       cpuname = "C3 'Nehemiah B' [C5N]";
+                       memcpy (clock_ratio, nehemiah_b_clock_ratio, sizeof(nehemiah_b_clock_ratio));
+                       memcpy (eblcr_table, nehemiah_b_eblcr, sizeof(nehemiah_b_eblcr));
+                       break;
+               case 5 ... 15:
+                       cpuname = "C3 'Nehemiah C' [C5N]";
+                       memcpy (clock_ratio, nehemiah_c_clock_ratio, sizeof(nehemiah_c_clock_ratio));
+                       memcpy (eblcr_table, nehemiah_c_eblcr, sizeof(nehemiah_c_eblcr));
+                       break;
+               }
                break;
+               
 
        default:
                cpuname = "Unknown";
index a14e8230c9a6164fe9c9c861fcc72a1f5db51005..2a495c162ec78153ccaf7e19c8188e6875f27909 100644 (file)
@@ -234,14 +234,15 @@ static int __initdata ezrat_eblcr[32] = {
 
 /*
  * VIA C3 Nehemiah */
-static int __initdata nehemiah_clock_ratio[32] = {
+ 
+static int __initdata nehemiah_a_clock_ratio[32] = {
        100, /* 0000 -> 10.0x */
        160, /* 0001 -> 16.0x */
-       -1,  /* 0010 -> RESERVED */
+       -1,  /* 0010 ->  RESERVED */
        90,  /* 0011 ->  9.0x */
        95,  /* 0100 ->  9.5x */
-       -1,  /* 0101 -> RESERVED */
-       -1,  /* 0110 -> RESERVED */
+       -1,  /* 0101 ->  RESERVED */
+       -1,  /* 0110 ->  RESERVED */
        55,  /* 0111 ->  5.5x */
        60,  /* 1000 ->  6.0x */
        70,  /* 1001 ->  7.0x */
@@ -250,8 +251,42 @@ static int __initdata nehemiah_clock_ratio[32] = {
        65,  /* 1100 ->  6.5x */
        75,  /* 1101 ->  7.5x */
        85,  /* 1110 ->  8.5x */
-       120, /* 1111 ->  12.0x */
+       120, /* 1111 -> 12.0x */
+       100, /* 0000 -> 10.0x */
+       -1,  /* 0001 -> RESERVED */
+       120, /* 0010 -> 12.0x */
+       90,  /* 0011 ->  9.0x */
+       105, /* 0100 -> 10.5x */
+       115, /* 0101 -> 11.5x */
+       125, /* 0110 -> 12.5x */
+       135, /* 0111 -> 13.5x */
+       140, /* 1000 -> 14.0x */
+       150, /* 1001 -> 15.0x */
+       160, /* 1010 -> 16.0x */
+       130, /* 1011 -> 13.0x */
+       145, /* 1100 -> 14.5x */
+       155, /* 1101 -> 15.5x */
+       -1,  /* 1110 -> RESERVED (13.0x) */
+       120, /* 1111 -> 12.0x */
+};
 
+static int __initdata  nehemiah_b_clock_ratio[32] = {
+       100, /* 0000 -> 10.0x */
+       160, /* 0001 -> 16.0x */
+       -1,  /* 0010 ->  RESERVED */
+       90,  /* 0011 ->  9.0x */
+       95,  /* 0100 ->  9.5x */
+       -1,  /* 0101 ->  RESERVED */
+       -1,  /* 0110 ->  RESERVED */
+       55,  /* 0111 ->  5.5x */
+       60,  /* 1000 ->  6.0x */
+       70,  /* 1001 ->  7.0x */
+       80,  /* 1010 ->  8.0x */
+       50,  /* 1011 ->  5.0x */
+       65,  /* 1100 ->  6.5x */
+       75,  /* 1101 ->  7.5x */
+       85,  /* 1110 ->  8.5x */
+       120, /* 1111 -> 12.0x */
        100, /* 0000 -> 10.0x */
        110, /* 0001 -> 11.0x */
        120, /* 0010 -> 12.0x */
@@ -266,18 +301,88 @@ static int __initdata nehemiah_clock_ratio[32] = {
        130, /* 1011 -> 13.0x */
        145, /* 1100 -> 14.5x */
        155, /* 1101 -> 15.5x */
-       -1,  /* 1110 -> RESERVED */
+       -1,  /* 1110 -> RESERVED (13.0x) */
        120, /* 1111 -> 12.0x */
 };
 
-static int __initdata nehemiah_eblcr[32] = {
+static int __initdata  nehemiah_c_clock_ratio[32] = {
+       100, /* 0000 -> 10.0x */
+       160, /* 0001 -> 16.0x */
+       40,  /* 0010 ->  RESERVED */
+       90,  /* 0011 ->  9.0x */
+       95,  /* 0100 ->  9.5x */
+       -1,  /* 0101 ->  RESERVED */
+       45,  /* 0110 ->  RESERVED */
+       55,  /* 0111 ->  5.5x */
+       60,  /* 1000 ->  6.0x */
+       70,  /* 1001 ->  7.0x */
+       80,  /* 1010 ->  8.0x */
+       50,  /* 1011 ->  5.0x */
+       65,  /* 1100 ->  6.5x */
+       75,  /* 1101 ->  7.5x */
+       85,  /* 1110 ->  8.5x */
+       120, /* 1111 -> 12.0x */
+       100, /* 0000 -> 10.0x */
+       110, /* 0001 -> 11.0x */
+       120, /* 0010 -> 12.0x */
+       90,  /* 0011 ->  9.0x */
+       105, /* 0100 -> 10.5x */
+       115, /* 0101 -> 11.5x */
+       125, /* 0110 -> 12.5x */
+       135, /* 0111 -> 13.5x */
+       140, /* 1000 -> 14.0x */
+       150, /* 1001 -> 15.0x */
+       160, /* 1010 -> 16.0x */
+       130, /* 1011 -> 13.0x */
+       145, /* 1100 -> 14.5x */
+       155, /* 1101 -> 15.5x */
+       -1,  /* 1110 -> RESERVED (13.0x) */
+       120, /* 1111 -> 12.0x */
+};
+
+static int __initdata nehemiah_a_eblcr[32] = {
        50,  /* 0000 ->  5.0x */
        160, /* 0001 -> 16.0x */
-       -1,  /* 0010 -> RESERVED */
+       -1,  /* 0010 ->  RESERVED */
        100, /* 0011 -> 10.0x */
        55,  /* 0100 ->  5.5x */
-       -1,  /* 0101 -> RESERVED */
-       -1,  /* 0110 -> RESERVED */
+       -1,  /* 0101 ->  RESERVED */
+       -1,  /* 0110 ->  RESERVED */
+       95,  /* 0111 ->  9.5x */
+       90,  /* 1000 ->  9.0x */
+       70,  /* 1001 ->  7.0x */
+       80,  /* 1010 ->  8.0x */
+       60,  /* 1011 ->  6.0x */
+       120, /* 1100 -> 12.0x */
+       75,  /* 1101 ->  7.5x */
+       85,  /* 1110 ->  8.5x */
+       65,  /* 1111 ->  6.5x */
+       90,  /* 0000 ->  9.0x */
+       -1,  /* 0001 -> RESERVED */
+       120, /* 0010 -> 12.0x */
+       100, /* 0011 -> 10.0x */
+       135, /* 0100 -> 13.5x */
+       115, /* 0101 -> 11.5x */
+       125, /* 0110 -> 12.5x */
+       105, /* 0111 -> 10.5x */
+       130, /* 1000 -> 13.0x */
+       150, /* 1001 -> 15.0x */
+       160, /* 1010 -> 16.0x */
+       140, /* 1011 -> 14.0x */
+       120, /* 1100 -> 12.0x */
+       155, /* 1101 -> 15.5x */
+       -1,  /* 1110 -> RESERVED (13.0x) */
+       145 /* 1111 -> 14.5x */
+   /* end of table  */
+};
+static int __initdata nehemiah_b_eblcr[32] = {
+       50,  /* 0000 ->  5.0x */
+       160, /* 0001 -> 16.0x */
+       -1,  /* 0010 ->  RESERVED */
+       100, /* 0011 -> 10.0x */
+       55,  /* 0100 ->  5.5x */
+       -1,  /* 0101 ->  RESERVED */
+       -1,  /* 0110 ->  RESERVED */
        95,  /* 0111 ->  9.5x */
        90,  /* 1000 ->  9.0x */
        70,  /* 1001 ->  7.0x */
@@ -287,7 +392,6 @@ static int __initdata nehemiah_eblcr[32] = {
        75,  /* 1101 ->  7.5x */
        85,  /* 1110 ->  8.5x */
        65,  /* 1111 ->  6.5x */
-
        90,  /* 0000 ->  9.0x */
        110, /* 0001 -> 11.0x */
        120, /* 0010 -> 12.0x */
@@ -302,9 +406,46 @@ static int __initdata nehemiah_eblcr[32] = {
        140, /* 1011 -> 14.0x */
        120, /* 1100 -> 12.0x */
        155, /* 1101 -> 15.5x */
-       -1,  /* 1110 -> RESERVED */
-       -1,  /* 1111 -> RESERVED */
+       -1,  /* 1110 -> RESERVED (13.0x) */
+       145 /* 1111 -> 14.5x */
+          /* end of table  */
 };
+static int __initdata nehemiah_c_eblcr[32] = {
+       50,  /* 0000 ->  5.0x */
+       160, /* 0001 -> 16.0x */
+       40,  /* 0010 ->  RESERVED */
+       100, /* 0011 -> 10.0x */
+       55,  /* 0100 ->  5.5x */
+       -1,  /* 0101 ->  RESERVED */
+       45,  /* 0110 ->  RESERVED */
+       95,  /* 0111 ->  9.5x */
+       90,  /* 1000 ->  9.0x */
+       70,  /* 1001 ->  7.0x */
+       80,  /* 1010 ->  8.0x */
+       60,  /* 1011 ->  6.0x */
+       120, /* 1100 -> 12.0x */
+       75,  /* 1101 ->  7.5x */
+       85,  /* 1110 ->  8.5x */
+       65,  /* 1111 ->  6.5x */
+       90,  /* 0000 ->  9.0x */
+       110, /* 0001 -> 11.0x */
+       120, /* 0010 -> 12.0x */
+       100, /* 0011 -> 10.0x */
+       135, /* 0100 -> 13.5x */
+       115, /* 0101 -> 11.5x */
+       125, /* 0110 -> 12.5x */
+       105, /* 0111 -> 10.5x */
+       130, /* 1000 -> 13.0x */
+       150, /* 1001 -> 15.0x */
+       160, /* 1010 -> 16.0x */
+       140, /* 1011 -> 14.0x */
+       120, /* 1100 -> 12.0x */
+       155, /* 1101 -> 15.5x */
+       -1,  /* 1110 -> RESERVED (13.0x) */
+       145 /* 1111 -> 14.5x */
+         /* end of table  */
+};
+
 /* 
  * Voltage scales. Div/Mod by 1000 to get actual voltage.
  * Which scale to use depends on the VRM type in use.