aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c44
1 files changed, 14 insertions, 30 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index fd70c77acc1c..f152c291e7c8 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -318,12 +318,12 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
318 318
319#define ROUNDING 0xf 319#define ROUNDING 0xf
320 320
321static int _guess(int guess) 321static int _guess(int guess, int mult)
322{ 322{
323 int target; 323 int target;
324 324
325 target = ((maxmult/10)*guess); 325 target = ((mult/10)*guess);
326 if (maxmult%10 != 0) 326 if (mult%10 != 0)
327 target += (guess/2); 327 target += (guess/2);
328 target += ROUNDING/2; 328 target += ROUNDING/2;
329 target &= ~ROUNDING; 329 target &= ~ROUNDING;
@@ -331,17 +331,17 @@ static int _guess(int guess)
331} 331}
332 332
333 333
334static int guess_fsb(void) 334static int guess_fsb(int mult)
335{ 335{
336 int speed = (cpu_khz/1000); 336 int speed = (cpu_khz/1000);
337 int i; 337 int i;
338 int speeds[3] = { 66, 100, 133 }; 338 int speeds[] = { 66, 100, 133, 200 };
339 339
340 speed += ROUNDING/2; 340 speed += ROUNDING/2;
341 speed &= ~ROUNDING; 341 speed &= ~ROUNDING;
342 342
343 for (i=0; i<3; i++) { 343 for (i=0; i<4; i++) {
344 if (_guess(speeds[i]) == speed) 344 if (_guess(speeds[i], mult) == speed)
345 return speeds[i]; 345 return speeds[i];
346 } 346 }
347 return 0; 347 return 0;
@@ -361,6 +361,7 @@ static int __init longhaul_get_ranges(void)
361 unsigned long lo, hi; 361 unsigned long lo, hi;
362 unsigned int eblcr_fsb_table_v1[] = { 66, 133, 100, -1 }; 362 unsigned int eblcr_fsb_table_v1[] = { 66, 133, 100, -1 };
363 unsigned int eblcr_fsb_table_v2[] = { 133, 100, -1, 66 }; 363 unsigned int eblcr_fsb_table_v2[] = { 133, 100, -1, 66 };
364 int mult;
364 365
365 switch (longhaul_version) { 366 switch (longhaul_version) {
366 case TYPE_LONGHAUL_V1: 367 case TYPE_LONGHAUL_V1:
@@ -368,30 +369,18 @@ static int __init longhaul_get_ranges(void)
368 /* Ugh, Longhaul v1 didn't have the min/max MSRs. 369 /* Ugh, Longhaul v1 didn't have the min/max MSRs.
369 Assume min=3.0x & max = whatever we booted at. */ 370 Assume min=3.0x & max = whatever we booted at. */
370 minmult = 30; 371 minmult = 30;
371 maxmult = longhaul_get_cpu_mult(); 372 maxmult = mult = longhaul_get_cpu_mult();
372 rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
373 invalue = (lo & (1<<18|1<<19)) >>18;
374 if (cpu_model==CPU_SAMUEL || cpu_model==CPU_SAMUEL2)
375 fsb = eblcr_fsb_table_v1[invalue];
376 else
377 fsb = guess_fsb();
378 break; 373 break;
379 374
380 case TYPE_POWERSAVER: 375 case TYPE_POWERSAVER:
381 /* Ezra-T */ 376 /* Ezra-T */
382 if (cpu_model==CPU_EZRA_T) { 377 if (cpu_model==CPU_EZRA_T) {
378 minmult = 30;
383 rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); 379 rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
384 invalue = longhaul.bits.MaxMHzBR; 380 invalue = longhaul.bits.MaxMHzBR;
385 if (longhaul.bits.MaxMHzBR4) 381 if (longhaul.bits.MaxMHzBR4)
386 invalue += 16; 382 invalue += 16;
387 maxmult=ezra_t_multipliers[invalue]; 383 maxmult = mult = ezra_t_multipliers[invalue];
388
389 invalue = longhaul.bits.MinMHzBR;
390 if (longhaul.bits.MinMHzBR4 == 1)
391 minmult = 30;
392 else
393 minmult = ezra_t_multipliers[invalue];
394 fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB];
395 break; 384 break;
396 } 385 }
397 386
@@ -411,21 +400,16 @@ static int __init longhaul_get_ranges(void)
411 * But it works, so we don't grumble. 400 * But it works, so we don't grumble.
412 */ 401 */
413 minmult=40; 402 minmult=40;
414 maxmult=longhaul_get_cpu_mult(); 403 maxmult = mult = longhaul_get_cpu_mult();
415
416 /* Starting with the 1.2GHz parts, theres a 200MHz bus. */
417 if ((cpu_khz/maxmult) > 13400)
418 fsb = 200;
419 else
420 fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB];
421 break; 404 break;
422 } 405 }
423 } 406 }
407 fsb = guess_fsb(mult);
424 408
425 dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n", 409 dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n",
426 minmult/10, minmult%10, maxmult/10, maxmult%10); 410 minmult/10, minmult%10, maxmult/10, maxmult%10);
427 411
428 if (fsb == -1) { 412 if (fsb == 0) {
429 printk (KERN_INFO PFX "Invalid (reserved) FSB!\n"); 413 printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
430 return -EINVAL; 414 return -EINVAL;
431 } 415 }