diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/longhaul.c | 44 |
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 | ||
321 | static int _guess(int guess) | 321 | static 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 | ||
334 | static int guess_fsb(void) | 334 | static 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 | } |