[CPUFREQ] Longhaul - Always guess FSB

This is patch that solves Ebox mini PC issue and make
FSB code more specification compilant. At start guess_fsb
function is guessing 200MHz FSB too. It is better to
make it in this way because, thanks to this function, driver
will fail for bogus FSB values caused by bogus multiplier
value. For PowerSaver processors we can't depend on Max /
MinMHzFSB because these values are only used for
PowerSaver 2.0 and 3.0. Most processors on which Longhaul
is used are PowerSaver 1.0 only. I'm changing code for older
CPU's too, but not so much as previously, and this code was
already used for Ezra. Using MinMHzBR for Ezra-T is outside
spec. It is for voltage scaling purpose and don't have to
be equal to minmult (but it is). Same for Nehemiah (it
isn't for sure). Added mult - current multiplier value.

Signed-off-by: Rafa� Bilski <rafalbilski@interia.pl>
Signed-off-by: Dave Jones <davej@redhat.com>

authored by Rafa� Bilski and committed by Dave Jones 24ebead8 264166e6

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