Commit 31085687 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-dj.bkbits.net/cpufreq

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 9e12ea16 7855776c
...@@ -54,7 +54,7 @@ cpufreq_driver.name - The name of this driver. ...@@ -54,7 +54,7 @@ cpufreq_driver.name - The name of this driver.
cpufreq_driver.init - A pointer to the per-CPU initialization cpufreq_driver.init - A pointer to the per-CPU initialization
function. function.
cpufreq_driver.verify - A pointer to a "verification" funciton. cpufreq_driver.verify - A pointer to a "verification" function.
cpufreq_driver.setpolicy _or_ cpufreq_driver.setpolicy _or_
cpufreq_driver.target - See below on the differences. cpufreq_driver.target - See below on the differences.
......
...@@ -444,7 +444,7 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) ...@@ -444,7 +444,7 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
/* /*
* cpufreq_gx_init: * cpufreq_gx_init:
* MediaGX/Geode GX initilize cpufreq driver * MediaGX/Geode GX initialize cpufreq driver
*/ */
static struct cpufreq_driver gx_suspmod_driver = { static struct cpufreq_driver gx_suspmod_driver = {
.verify = cpufreq_gx_verify, .verify = cpufreq_gx_verify,
......
...@@ -40,18 +40,15 @@ ...@@ -40,18 +40,15 @@
#define dprintk(msg...) do { } while(0); #define dprintk(msg...) do { } while(0);
#endif #endif
static int numscales=16, numvscales; static unsigned int numscales=16, numvscales;
static int minvid, maxvid; static int minvid, maxvid;
static int can_scale_voltage; static int can_scale_voltage;
static int can_scale_fsb;
static int vrmrev; static int vrmrev;
/* Module parameters */ /* Module parameters */
static int prefer_slow_fsb;
static int dont_scale_voltage; static int dont_scale_voltage;
static int dont_scale_fsb; static unsigned int fsb;
static int current_fsb;
#define __hlt() __asm__ __volatile__("hlt": : :"memory") #define __hlt() __asm__ __volatile__("hlt": : :"memory")
...@@ -231,14 +228,6 @@ static int __initdata c5m_eblcr[32] = { ...@@ -231,14 +228,6 @@ static int __initdata c5m_eblcr[32] = {
145, /* 1111 -> 14.5x */ 145, /* 1111 -> 14.5x */
}; };
/* fsb values as defined in CPU */
static unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
/* fsb values to favour low fsb speed (lower power) */
static unsigned int power_fsb_table[] = { 66, 100, 133, -1 };
/* fsb values to favour high fsb speed (for e.g. if lowering CPU
freq because of heat, but want to maintain highest performance possible) */
static unsigned int perf_fsb_table[] = { 133, 100, 66, -1 };
/* Voltage scales. Div by 1000 to get actual voltage. */ /* Voltage scales. Div by 1000 to get actual voltage. */
static int __initdata vrm85scales[32] = { static int __initdata vrm85scales[32] = {
1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700, 1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700,
...@@ -258,21 +247,22 @@ static int __initdata mobilevrmscales[32] = { ...@@ -258,21 +247,22 @@ static int __initdata mobilevrmscales[32] = {
static int clock_ratio[32]; static int clock_ratio[32];
static int eblcr_table[32]; static int eblcr_table[32];
static int voltage_table[32]; static int voltage_table[32];
static int highest_speed, lowest_speed; /* kHz */ static unsigned int highest_speed, lowest_speed; /* kHz */
static int longhaul; /* version. */ static int longhaul; /* version. */
static struct cpufreq_frequency_table *longhaul_table; static struct cpufreq_frequency_table *longhaul_table;
static int longhaul_get_cpu_fsb (void) static int longhaul_get_cpu_fsb (void)
{ {
unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
unsigned long invalue=0,lo, hi; unsigned long invalue=0,lo, hi;
if (current_fsb == 0) { if (fsb == 0) {
rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
invalue = (lo & (1<<18|1<<19)) >>18; invalue = (lo & (1<<18|1<<19)) >>18;
return eblcr_fsb_table[invalue]; return eblcr_fsb_table[invalue];
} else { } else {
return current_fsb; return fsb;
} }
} }
...@@ -294,12 +284,11 @@ static int longhaul_get_cpu_mult (void) ...@@ -294,12 +284,11 @@ static int longhaul_get_cpu_mult (void)
/** /**
* longhaul_set_cpu_frequency() * longhaul_set_cpu_frequency()
* @clock_ratio_index : index of clock_ratio[] for new frequency * @clock_ratio_index : index of clock_ratio[] for new frequency
* @newfsb: the new FSB
* *
* Sets a new clock ratio, and -if applicable- a new Front Side Bus * Sets a new clock ratio, and -if applicable- a new Front Side Bus
*/ */
static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newfsb) static void longhaul_setstate (unsigned int clock_ratio_index)
{ {
unsigned long lo, hi; unsigned long lo, hi;
unsigned int bits; unsigned int bits;
...@@ -307,24 +296,21 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf ...@@ -307,24 +296,21 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf
int vidindex, i; int vidindex, i;
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
if (!newfsb || (clock_ratio[clock_ratio_index] == -1)) if (clock_ratio[clock_ratio_index] == -1)
return;
if ((!can_scale_fsb) && (newfsb != current_fsb))
return; return;
if (((clock_ratio[clock_ratio_index] * newfsb * 100) > highest_speed) || if (((clock_ratio[clock_ratio_index] * fsb * 100) > highest_speed) ||
((clock_ratio[clock_ratio_index] * newfsb * 100) < lowest_speed)) ((clock_ratio[clock_ratio_index] * fsb * 100) < lowest_speed))
return; return;
freqs.old = longhaul_get_cpu_mult() * longhaul_get_cpu_fsb() * 100; freqs.old = longhaul_get_cpu_mult() * longhaul_get_cpu_fsb() * 100;
freqs.new = clock_ratio[clock_ratio_index] * newfsb * 100; freqs.new = clock_ratio[clock_ratio_index] * fsb * 100;
freqs.cpu = 0; /* longhaul.c is UP only driver */ freqs.cpu = 0; /* longhaul.c is UP only driver */
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
dprintk (KERN_INFO "longhaul: New FSB:%d Mult(x10):%d\n", dprintk (KERN_INFO "longhaul: FSB:%d Mult(x10):%d\n",
newfsb, clock_ratio[clock_ratio_index]); fsb * 100, clock_ratio[clock_ratio_index]);
bits = clock_ratio_index; bits = clock_ratio_index;
/* "bits" contains the bitpattern of the new multiplier. /* "bits" contains the bitpattern of the new multiplier.
...@@ -358,14 +344,9 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf ...@@ -358,14 +344,9 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf
lo |= revkey; lo |= revkey;
if (can_scale_voltage) { if (can_scale_voltage) {
if (can_scale_fsb==1) { /* PB: TODO fix this up */
dprintk (KERN_INFO "longhaul: Voltage scaling + FSB scaling not done yet.\n"); vidindex = (((highest_speed-lowest_speed) / (fsb/2)) -
goto bad_voltage; ((highest_speed-((clock_ratio[clock_ratio_index] * fsb * 100)/1000)) / (fsb/2)));
} else {
/* PB: TODO fix this up */
vidindex = (((highest_speed-lowest_speed) / (newfsb/2)) -
((highest_speed-((clock_ratio[clock_ratio_index] * newfsb * 100)/1000)) / (newfsb/2)));
}
for (i=0;i<32;i++) { for (i=0;i<32;i++) {
dprintk (KERN_INFO "VID hunting. Looking for %d, found %d\n", dprintk (KERN_INFO "VID hunting. Looking for %d, found %d\n",
minvid+(vidindex*25), voltage_table[i]); minvid+(vidindex*25), voltage_table[i]);
...@@ -403,17 +384,6 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf ...@@ -403,17 +384,6 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf
lo |= (1<<8); /* EnableSoftBusRatio */ lo |= (1<<8); /* EnableSoftBusRatio */
lo |= revkey; lo |= revkey;
/* Set FSB */
if (can_scale_fsb==1) {
lo &= ~(1<<28|1<<29);
switch (newfsb) {
case 66: lo |= (1<<28|1<<29); /* 11 */
break;
case 100: lo |= 1<<28; /* 01 */
break;
case 133: break; /* 00*/
}
}
wrmsr (MSR_VIA_LONGHAUL, lo, hi); wrmsr (MSR_VIA_LONGHAUL, lo, hi);
__hlt(); __hlt();
...@@ -431,14 +401,11 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf ...@@ -431,14 +401,11 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf
static int __init longhaul_get_ranges (void) static int __init longhaul_get_ranges (void)
{ {
unsigned long lo, hi, invalue; unsigned long lo, hi, invalue;
unsigned int minmult=0, maxmult=0, minfsb=0, maxfsb=0; unsigned int minmult=0, maxmult=0;
unsigned int multipliers[32]= { unsigned int multipliers[32]= {
50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65, 50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
-1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 }; -1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
unsigned int fsb_table[4] = { 133, 100, -1, 66 }; unsigned int j, k = 0;
unsigned int fsbcount = 1;
unsigned int i, j, k = 0;
static unsigned int *fsb_search_table;
switch (longhaul) { switch (longhaul) {
case 1: case 1:
...@@ -446,7 +413,6 @@ static int __init longhaul_get_ranges (void) ...@@ -446,7 +413,6 @@ static int __init longhaul_get_ranges (void)
Assume min=3.0x & max = whatever we booted at. */ Assume min=3.0x & max = whatever we booted at. */
minmult = 30; minmult = 30;
maxmult = longhaul_get_cpu_mult(); maxmult = longhaul_get_cpu_mult();
minfsb = maxfsb = current_fsb;
break; break;
case 2 ... 3: case 2 ... 3:
...@@ -465,55 +431,30 @@ static int __init longhaul_get_ranges (void) ...@@ -465,55 +431,30 @@ static int __init longhaul_get_ranges (void)
#else #else
minmult = 30; /* as per spec */ minmult = 30; /* as per spec */
#endif #endif
if (can_scale_fsb==1) {
invalue = (hi & (1<<9|1<<10)) >> 9;
maxfsb = fsb_table[invalue];
invalue = (hi & (1<<25|1<<26)) >> 25;
minfsb = fsb_table[invalue];
dprintk (KERN_INFO "longhaul: Min FSB=%d Max FSB=%d\n",
minfsb, maxfsb);
fsbcount = 0;
for (i=0;i<4;i++) {
if((fsb_table[i] >= minfsb) && (fsb_table[i] <= maxfsb))
fsbcount++;
}
} else {
minfsb = maxfsb = current_fsb;
}
break; break;
} }
highest_speed = maxmult * maxfsb * 100; highest_speed = maxmult * fsb * 100;
lowest_speed = minmult * minfsb * 100; lowest_speed = minmult * fsb * 100;
dprintk (KERN_INFO "longhaul: MinMult(x10)=%d MaxMult(x10)=%d\n", dprintk (KERN_INFO "longhaul: MinMult(x10)=%d MaxMult(x10)=%d\n",
minmult, maxmult); minmult, maxmult);
dprintk (KERN_INFO "longhaul: Lowestspeed=%d Highestspeed=%d\n", dprintk (KERN_INFO "longhaul: Lowestspeed=%d Highestspeed=%d\n",
lowest_speed, highest_speed); lowest_speed, highest_speed);
longhaul_table = kmalloc((numscales * fsbcount + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL); longhaul_table = kmalloc((numscales + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
if(!longhaul_table) if(!longhaul_table)
return -ENOMEM; return -ENOMEM;
if (prefer_slow_fsb) for (j=0; (j<numscales); j++) {
fsb_search_table = perf_fsb_table; // yep, this is right: the last entry is preferred by cpufreq_frequency_table_* ... if (clock_ratio[j] == -1)
else
fsb_search_table = power_fsb_table;
for (i=0; (i<4); i++) {
if ((fsb_search_table[i] > maxfsb) || (fsb_search_table[i] < minfsb) || (fsb_search_table[i] == -1))
continue; continue;
for (j=0; (j<numscales); j++) { if (((unsigned int)clock_ratio[j] > maxmult) || ((unsigned int)clock_ratio[j] < minmult))
if ((clock_ratio[j] > maxmult) || (clock_ratio[j] < minmult) || (clock_ratio[j] == -1)) continue;
continue; longhaul_table[k].frequency= clock_ratio[j] * fsb * 100;
longhaul_table[k].frequency= clock_ratio[j] * fsb_search_table[i] * 100; longhaul_table[k].index = (j << 8);
longhaul_table[k].index = (j << 8) | (i); k++;
k++;
}
} }
longhaul_table[k].frequency = CPUFREQ_TABLE_END; longhaul_table[k].frequency = CPUFREQ_TABLE_END;
if (!k) if (!k)
return -EINVAL; return -EINVAL;
...@@ -568,16 +509,14 @@ static int longhaul_target (struct cpufreq_policy *policy, ...@@ -568,16 +509,14 @@ static int longhaul_target (struct cpufreq_policy *policy,
unsigned int relation) unsigned int relation)
{ {
unsigned int table_index = 0; unsigned int table_index = 0;
unsigned int new_fsb = 0;
unsigned int new_clock_ratio = 0; unsigned int new_clock_ratio = 0;
if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index)) if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
return -EINVAL; return -EINVAL;
new_clock_ratio = longhaul_table[table_index].index & 0xFF; new_clock_ratio = longhaul_table[table_index].index & 0xFF;
new_fsb = power_fsb_table[(longhaul_table[table_index].index & 0xFF00) >> 8];
longhaul_setstate(new_clock_ratio, new_fsb); longhaul_setstate(new_clock_ratio);
return 0; return 0;
} }
...@@ -628,9 +567,6 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -628,9 +567,6 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
rdmsr (MSR_VIA_LONGHAUL, lo, hi); rdmsr (MSR_VIA_LONGHAUL, lo, hi);
if ((lo & (1<<0)) && (dont_scale_voltage==0)) if ((lo & (1<<0)) && (dont_scale_voltage==0))
longhaul_setup_voltagescaling (lo, hi); longhaul_setup_voltagescaling (lo, hi);
if ((lo & (1<<1)) && (dont_scale_fsb==0) && (current_fsb==0))
can_scale_fsb = 1;
} }
if (longhaul_get_ranges()) if (longhaul_get_ranges())
...@@ -639,7 +575,7 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -639,7 +575,7 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
policy->policy = CPUFREQ_POLICY_PERFORMANCE; policy->policy = CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = (unsigned int) (longhaul_get_cpu_fsb() * longhaul_get_cpu_mult() * 100); policy->cur = (unsigned int) (longhaul_get_cpu_fsb() * longhaul_get_cpu_mult() * 100);
return cpufreq_frequency_table_cpuinfo(policy, longhaul_table); return cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
} }
...@@ -677,10 +613,7 @@ static void __exit longhaul_exit (void) ...@@ -677,10 +613,7 @@ static void __exit longhaul_exit (void)
kfree(longhaul_table); kfree(longhaul_table);
} }
MODULE_PARM (dont_scale_fsb, "i");
MODULE_PARM (dont_scale_voltage, "i"); MODULE_PARM (dont_scale_voltage, "i");
MODULE_PARM (current_fsb, "i");
MODULE_PARM (prefer_slow_fsb, "i");
MODULE_AUTHOR ("Dave Jones <davej@suse.de>"); MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
......
...@@ -151,7 +151,7 @@ static int check_powernow(void) ...@@ -151,7 +151,7 @@ static int check_powernow(void)
} }
if (!(edx & (1 << 1 | 1 << 2))) { if (!(edx & (1 << 1 | 1 << 2))) {
printk (" nothing.\n"); printk ("nothing.\n");
return 0; return 0;
} }
...@@ -162,9 +162,8 @@ static int check_powernow(void) ...@@ -162,9 +162,8 @@ static int check_powernow(void)
static int get_ranges (unsigned char *pst) static int get_ranges (unsigned char *pst)
{ {
int j; unsigned int j, speed;
u8 fid, vid; u8 fid, vid;
unsigned int speed;
powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL); powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
if (!powernow_table) if (!powernow_table)
...@@ -258,7 +257,7 @@ static void change_speed (unsigned int index) ...@@ -258,7 +257,7 @@ static void change_speed (unsigned int index)
} }
int powernow_decode_bios (int maxfid, int startvid) static int powernow_decode_bios (int maxfid, int startvid)
{ {
struct psb_s *psb; struct psb_s *psb;
struct pst_s *pst; struct pst_s *pst;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment