1/* 2 * AMD K7 Powernow driver. 3 * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs. 4 * (C) 2003-2004 Dave Jones <davej@redhat.com> 5 * 6 * Licensed under the terms of the GNU GPL License version 2. 7 * Based upon datasheets & sample CPUs kindly provided by AMD. 8 * 9 * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt. 10 * - We cli/sti on stepping A0 CPUs around the FID/VID transition. 11 * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect. 12 * - We disable half multipliers if ACPI is used on A0 stepping CPUs. 13 */ 14 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/moduleparam.h> 18#include <linux/init.h> 19#include <linux/cpufreq.h> 20#include <linux/slab.h> 21#include <linux/string.h> 22#include <linux/dmi.h> 23 24#include <asm/msr.h> 25#include <asm/timer.h> 26#include <asm/timex.h> 27#include <asm/io.h> 28#include <asm/system.h> 29 30#ifdef CONFIG_X86_POWERNOW_K7_ACPI 31#include <linux/acpi.h> 32#include <acpi/processor.h> 33#endif 34 35#include "powernow-k7.h" 36 37#define PFX "powernow: " 38 39 40struct psb_s { 41 u8 signature[10]; 42 u8 tableversion; 43 u8 flags; 44 u16 settlingtime; 45 u8 reserved1; 46 u8 numpst; 47}; 48 49struct pst_s { 50 u32 cpuid; 51 u8 fsbspeed; 52 u8 maxfid; 53 u8 startvid; 54 u8 numpstates; 55}; 56 57#ifdef CONFIG_X86_POWERNOW_K7_ACPI 58union powernow_acpi_control_t { 59 struct { 60 unsigned long fid:5, 61 vid:5, 62 sgtc:20, 63 res1:2; 64 } bits; 65 unsigned long val; 66}; 67#endif 68 69#ifdef CONFIG_CPU_FREQ_DEBUG 70/* divide by 1000 to get VCore voltage in V. */ 71static const int mobile_vid_table[32] = { 72 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, 73 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, 74 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, 75 1075, 1050, 1025, 1000, 975, 950, 925, 0, 76}; 77#endif 78 79/* divide by 10 to get FID. */ 80static const int fid_codes[32] = { 81 110, 115, 120, 125, 50, 55, 60, 65, 82 70, 75, 80, 85, 90, 95, 100, 105, 83 30, 190, 40, 200, 130, 135, 140, 210, 84 150, 225, 160, 165, 170, 180, -1, -1, 85}; 86 87/* This parameter is used in order to force ACPI instead of legacy method for 88 * configuration purpose. 89 */ 90 91static int acpi_force; 92 93static struct cpufreq_frequency_table *powernow_table; 94 95static unsigned int can_scale_bus; 96static unsigned int can_scale_vid; 97static unsigned int minimum_speed=-1; 98static unsigned int maximum_speed; 99static unsigned int number_scales; 100static unsigned int fsb; 101static unsigned int latency; 102static char have_a0; 103 104#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k7", msg) 105 106static int check_fsb(unsigned int fsbspeed) 107{ 108 int delta; 109 unsigned int f = fsb / 1000; 110 111 delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed; 112 return (delta < 5); 113} 114 115static int check_powernow(void) 116{ 117 struct cpuinfo_x86 *c = cpu_data; 118 unsigned int maxei, eax, ebx, ecx, edx; 119 120 if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) { 121#ifdef MODULE 122 printk (KERN_INFO PFX "This module only works with AMD K7 CPUs\n"); 123#endif 124 return 0; 125 } 126 127 /* Get maximum capabilities */ 128 maxei = cpuid_eax (0x80000000); 129 if (maxei < 0x80000007) { /* Any powernow info ? */ 130#ifdef MODULE 131 printk (KERN_INFO PFX "No powernow capabilities detected\n"); 132#endif 133 return 0; 134 } 135 136 if ((c->x86_model == 6) && (c->x86_mask == 0)) { 137 printk (KERN_INFO PFX "K7 660[A0] core detected, enabling errata workarounds\n"); 138 have_a0 = 1; 139 } 140 141 cpuid(0x80000007, &eax, &ebx, &ecx, &edx); 142 143 /* Check we can actually do something before we say anything.*/ 144 if (!(edx & (1 << 1 | 1 << 2))) 145 return 0; 146 147 printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: "); 148 149 if (edx & 1 << 1) { 150 printk ("frequency"); 151 can_scale_bus=1; 152 } 153 154 if ((edx & (1 << 1 | 1 << 2)) == 0x6) 155 printk (" and "); 156 157 if (edx & 1 << 2) { 158 printk ("voltage"); 159 can_scale_vid=1; 160 } 161 162 printk (".\n"); 163 return 1; 164} 165 166 167static int get_ranges (unsigned char *pst) 168{ 169 unsigned int j; 170 unsigned int speed; 171 u8 fid, vid; 172 173 powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL); 174 if (!powernow_table) 175 return -ENOMEM; 176 177 for (j=0 ; j < number_scales; j++) { 178 fid = *pst++; 179 180 powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10; 181 powernow_table[j].index = fid; /* lower 8 bits */ 182 183 speed = powernow_table[j].frequency; 184 185 if ((fid_codes[fid] % 10)==5) { 186#ifdef CONFIG_X86_POWERNOW_K7_ACPI 187 if (have_a0 == 1) 188 powernow_table[j].frequency = CPUFREQ_ENTRY_INVALID; 189#endif 190 } 191 192 if (speed < minimum_speed) 193 minimum_speed = speed; 194 if (speed > maximum_speed) 195 maximum_speed = speed; 196 197 vid = *pst++; 198 powernow_table[j].index |= (vid << 8); /* upper 8 bits */ 199 200 dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " 201 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, 202 fid_codes[fid] % 10, speed/1000, vid, 203 mobile_vid_table[vid]/1000, 204 mobile_vid_table[vid]%1000); 205 } 206 powernow_table[number_scales].frequency = CPUFREQ_TABLE_END; 207 powernow_table[number_scales].index = 0; 208 209 return 0; 210} 211 212 213static void change_FID(int fid) 214{ 215 union msr_fidvidctl fidvidctl; 216 217 rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); 218 if (fidvidctl.bits.FID != fid) { 219 fidvidctl.bits.SGTC = latency; 220 fidvidctl.bits.FID = fid; 221 fidvidctl.bits.VIDC = 0; 222 fidvidctl.bits.FIDC = 1; 223 wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); 224 } 225} 226 227 228static void change_VID(int vid) 229{ 230 union msr_fidvidctl fidvidctl; 231 232 rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); 233 if (fidvidctl.bits.VID != vid) { 234 fidvidctl.bits.SGTC = latency; 235 fidvidctl.bits.VID = vid; 236 fidvidctl.bits.FIDC = 0; 237 fidvidctl.bits.VIDC = 1; 238 wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val); 239 } 240} 241 242 243static void change_speed (unsigned int index) 244{ 245 u8 fid, vid; 246 struct cpufreq_freqs freqs; 247 union msr_fidvidstatus fidvidstatus; 248 int cfid; 249 250 /* fid are the lower 8 bits of the index we stored into 251 * the cpufreq frequency table in powernow_decode_bios, 252 * vid are the upper 8 bits. 253 */ 254 255 fid = powernow_table[index].index & 0xFF; 256 vid = (powernow_table[index].index & 0xFF00) >> 8; 257 258 freqs.cpu = 0; 259 260 rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); 261 cfid = fidvidstatus.bits.CFID; 262 freqs.old = fsb * fid_codes[cfid] / 10; 263 264 freqs.new = powernow_table[index].frequency; 265 266 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 267 268 /* Now do the magic poking into the MSRs. */ 269 270 if (have_a0 == 1) /* A0 errata 5 */ 271 local_irq_disable(); 272 273 if (freqs.old > freqs.new) { 274 /* Going down, so change FID first */ 275 change_FID(fid); 276 change_VID(vid); 277 } else { 278 /* Going up, so change VID first */ 279 change_VID(vid); 280 change_FID(fid); 281 } 282 283 284 if (have_a0 == 1) 285 local_irq_enable(); 286 287 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 288} 289 290 291#ifdef CONFIG_X86_POWERNOW_K7_ACPI 292 293static struct acpi_processor_performance *acpi_processor_perf; 294 295static int powernow_acpi_init(void) 296{ 297 int i; 298 int retval = 0; 299 union powernow_acpi_control_t pc; 300 301 if (acpi_processor_perf != NULL && powernow_table != NULL) { 302 retval = -EINVAL; 303 goto err0; 304 } 305 306 acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance), 307 GFP_KERNEL); 308 if (!acpi_processor_perf) { 309 retval = -ENOMEM; 310 goto err0; 311 } 312 313 if (acpi_processor_register_performance(acpi_processor_perf, 0)) { 314 retval = -EIO; 315 goto err1; 316 } 317 318 if (acpi_processor_perf->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) { 319 retval = -ENODEV; 320 goto err2; 321 } 322 323 if (acpi_processor_perf->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) { 324 retval = -ENODEV; 325 goto err2; 326 } 327 328 number_scales = acpi_processor_perf->state_count; 329 330 if (number_scales < 2) { 331 retval = -ENODEV; 332 goto err2; 333 } 334 335 powernow_table = kzalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL); 336 if (!powernow_table) { 337 retval = -ENOMEM; 338 goto err2; 339 } 340 341 pc.val = (unsigned long) acpi_processor_perf->states[0].control; 342 for (i = 0; i < number_scales; i++) { 343 u8 fid, vid; 344 struct acpi_processor_px *state = 345 &acpi_processor_perf->states[i]; 346 unsigned int speed, speed_mhz; 347 348 pc.val = (unsigned long) state->control; 349 dprintk ("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", 350 i, 351 (u32) state->core_frequency, 352 (u32) state->power, 353 (u32) state->transition_latency, 354 (u32) state->control, 355 pc.bits.sgtc); 356 357 vid = pc.bits.vid; 358 fid = pc.bits.fid; 359 360 powernow_table[i].frequency = fsb * fid_codes[fid] / 10; 361 powernow_table[i].index = fid; /* lower 8 bits */ 362 powernow_table[i].index |= (vid << 8); /* upper 8 bits */ 363 364 speed = powernow_table[i].frequency; 365 speed_mhz = speed / 1000; 366 367 /* processor_perflib will multiply the MHz value by 1000 to 368 * get a KHz value (e.g. 1266000). However, powernow-k7 works 369 * with true KHz values (e.g. 1266768). To ensure that all 370 * powernow frequencies are available, we must ensure that 371 * ACPI doesn't restrict them, so we round up the MHz value 372 * to ensure that perflib's computed KHz value is greater than 373 * or equal to powernow's KHz value. 374 */ 375 if (speed % 1000 > 0) 376 speed_mhz++; 377 378 if ((fid_codes[fid] % 10)==5) { 379 if (have_a0 == 1) 380 powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; 381 } 382 383 dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " 384 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, 385 fid_codes[fid] % 10, speed_mhz, vid, 386 mobile_vid_table[vid]/1000, 387 mobile_vid_table[vid]%1000); 388 389 if (state->core_frequency != speed_mhz) { 390 state->core_frequency = speed_mhz; 391 dprintk(" Corrected ACPI frequency to %d\n", 392 speed_mhz); 393 } 394 395 if (latency < pc.bits.sgtc) 396 latency = pc.bits.sgtc; 397 398 if (speed < minimum_speed) 399 minimum_speed = speed; 400 if (speed > maximum_speed) 401 maximum_speed = speed; 402 } 403 404 powernow_table[i].frequency = CPUFREQ_TABLE_END; 405 powernow_table[i].index = 0; 406 407 /* notify BIOS that we exist */ 408 acpi_processor_notify_smm(THIS_MODULE); 409 410 return 0; 411 412err2: 413 acpi_processor_unregister_performance(acpi_processor_perf, 0); 414err1: 415 kfree(acpi_processor_perf); 416err0: 417 printk(KERN_WARNING PFX "ACPI perflib can not be used in this platform\n"); 418 acpi_processor_perf = NULL; 419 return retval; 420} 421#else 422static int powernow_acpi_init(void) 423{ 424 printk(KERN_INFO PFX "no support for ACPI processor found." 425 " Please recompile your kernel with ACPI processor\n"); 426 return -EINVAL; 427} 428#endif 429 430static int powernow_decode_bios (int maxfid, int startvid) 431{ 432 struct psb_s *psb; 433 struct pst_s *pst; 434 unsigned int i, j; 435 unsigned char *p; 436 unsigned int etuple; 437 unsigned int ret; 438 439 etuple = cpuid_eax(0x80000001); 440 441 for (i=0xC0000; i < 0xffff0 ; i+=16) { 442 443 p = phys_to_virt(i); 444 445 if (memcmp(p, "AMDK7PNOW!", 10) == 0){ 446 dprintk ("Found PSB header at %p\n", p); 447 psb = (struct psb_s *) p; 448 dprintk ("Table version: 0x%x\n", psb->tableversion); 449 if (psb->tableversion != 0x12) { 450 printk (KERN_INFO PFX "Sorry, only v1.2 tables supported right now\n"); 451 return -ENODEV; 452 } 453 454 dprintk ("Flags: 0x%x\n", psb->flags); 455 if ((psb->flags & 1)==0) { 456 dprintk ("Mobile voltage regulator\n"); 457 } else { 458 dprintk ("Desktop voltage regulator\n"); 459 } 460 461 latency = psb->settlingtime; 462 if (latency < 100) { 463 printk (KERN_INFO PFX "BIOS set settling time to %d microseconds." 464 "Should be at least 100. Correcting.\n", latency); 465 latency = 100; 466 } 467 dprintk ("Settling Time: %d microseconds.\n", psb->settlingtime); 468 dprintk ("Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst); 469 470 p += sizeof (struct psb_s); 471 472 pst = (struct pst_s *) p; 473 474 for (j=0; j<psb->numpst; j++) { 475 pst = (struct pst_s *) p; 476 number_scales = pst->numpstates; 477 478 if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) && 479 (maxfid==pst->maxfid) && (startvid==pst->startvid)) 480 { 481 dprintk ("PST:%d (@%p)\n", j, pst); 482 dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", 483 pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); 484 485 ret = get_ranges ((char *) pst + sizeof (struct pst_s)); 486 return ret; 487 } else { 488 unsigned int k; 489 p = (char *) pst + sizeof (struct pst_s); 490 for (k=0; k<number_scales; k++) 491 p+=2; 492 } 493 } 494 printk (KERN_INFO PFX "No PST tables match this cpuid (0x%x)\n", etuple); 495 printk (KERN_INFO PFX "This is indicative of a broken BIOS.\n"); 496 497 return -EINVAL; 498 } 499 p++; 500 } 501 502 return -ENODEV; 503} 504 505 506static int powernow_target (struct cpufreq_policy *policy, 507 unsigned int target_freq, 508 unsigned int relation) 509{ 510 unsigned int newstate; 511 512 if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, relation, &newstate)) 513 return -EINVAL; 514 515 change_speed(newstate); 516 517 return 0; 518} 519 520 521static int powernow_verify (struct cpufreq_policy *policy) 522{ 523 return cpufreq_frequency_table_verify(policy, powernow_table); 524} 525 526/* 527 * We use the fact that the bus frequency is somehow 528 * a multiple of 100000/3 khz, then we compute sgtc according 529 * to this multiple. 530 * That way, we match more how AMD thinks all of that work. 531 * We will then get the same kind of behaviour already tested under 532 * the "well-known" other OS. 533 */ 534static int __init fixup_sgtc(void) 535{ 536 unsigned int sgtc; 537 unsigned int m; 538 539 m = fsb / 3333; 540 if ((m % 10) >= 5) 541 m += 5; 542 543 m /= 10; 544 545 sgtc = 100 * m * latency; 546 sgtc = sgtc / 3; 547 if (sgtc > 0xfffff) { 548 printk(KERN_WARNING PFX "SGTC too large %d\n", sgtc); 549 sgtc = 0xfffff; 550 } 551 return sgtc; 552} 553 554static unsigned int powernow_get(unsigned int cpu) 555{ 556 union msr_fidvidstatus fidvidstatus; 557 unsigned int cfid; 558 559 if (cpu) 560 return 0; 561 rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); 562 cfid = fidvidstatus.bits.CFID; 563 564 return (fsb * fid_codes[cfid] / 10); 565} 566 567 568static int __init acer_cpufreq_pst(struct dmi_system_id *d) 569{ 570 printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident); 571 printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n"); 572 printk(KERN_WARNING "cpufreq scaling has been disabled as a result of this.\n"); 573 return 0; 574} 575 576/* 577 * Some Athlon laptops have really fucked PST tables. 578 * A BIOS update is all that can save them. 579 * Mention this, and disable cpufreq. 580 */ 581static struct dmi_system_id __initdata powernow_dmi_table[] = { 582 { 583 .callback = acer_cpufreq_pst, 584 .ident = "Acer Aspire", 585 .matches = { 586 DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"), 587 DMI_MATCH(DMI_BIOS_VERSION, "3A71"), 588 }, 589 }, 590 { } 591}; 592 593static int __init powernow_cpu_init (struct cpufreq_policy *policy) 594{ 595 union msr_fidvidstatus fidvidstatus; 596 int result; 597 598 if (policy->cpu != 0) 599 return -ENODEV; 600 601 rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); 602 603 recalibrate_cpu_khz(); 604 605 fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; 606 if (!fsb) { 607 printk(KERN_WARNING PFX "can not determine bus frequency\n"); 608 return -EINVAL; 609 } 610 dprintk("FSB: %3dMHz\n", fsb/1000); 611 612 if (dmi_check_system(powernow_dmi_table) || acpi_force) { 613 printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); 614 result = powernow_acpi_init(); 615 } else { 616 result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID); 617 if (result) { 618 printk (KERN_INFO PFX "Trying ACPI perflib\n"); 619 maximum_speed = 0; 620 minimum_speed = -1; 621 latency = 0; 622 result = powernow_acpi_init(); 623 if (result) { 624 printk (KERN_INFO PFX "ACPI and legacy methods failed\n"); 625 printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.html\n"); 626 } 627 } else { 628 /* SGTC use the bus clock as timer */ 629 latency = fixup_sgtc(); 630 printk(KERN_INFO PFX "SGTC: %d\n", latency); 631 } 632 } 633 634 if (result) 635 return result; 636 637 printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n", 638 minimum_speed/1000, maximum_speed/1000); 639 640 policy->governor = CPUFREQ_DEFAULT_GOVERNOR; 641 642 policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency); 643 644 policy->cur = powernow_get(0); 645 646 cpufreq_frequency_table_get_attr(powernow_table, policy->cpu); 647 648 return cpufreq_frequency_table_cpuinfo(policy, powernow_table); 649} 650 651static int powernow_cpu_exit (struct cpufreq_policy *policy) { 652 cpufreq_frequency_table_put_attr(policy->cpu); 653 654#ifdef CONFIG_X86_POWERNOW_K7_ACPI 655 if (acpi_processor_perf) { 656 acpi_processor_unregister_performance(acpi_processor_perf, 0); 657 kfree(acpi_processor_perf); 658 } 659#endif 660 661 kfree(powernow_table); 662 return 0; 663} 664 665static struct freq_attr* powernow_table_attr[] = { 666 &cpufreq_freq_attr_scaling_available_freqs, 667 NULL, 668}; 669 670static struct cpufreq_driver powernow_driver = { 671 .verify = powernow_verify, 672 .target = powernow_target, 673 .get = powernow_get, 674 .init = powernow_cpu_init, 675 .exit = powernow_cpu_exit, 676 .name = "powernow-k7", 677 .owner = THIS_MODULE, 678 .attr = powernow_table_attr, 679}; 680 681static int __init powernow_init (void) 682{ 683 if (check_powernow()==0) 684 return -ENODEV; 685 return cpufreq_register_driver(&powernow_driver); 686} 687 688 689static void __exit powernow_exit (void) 690{ 691 cpufreq_unregister_driver(&powernow_driver); 692} 693 694module_param(acpi_force, int, 0444); 695MODULE_PARM_DESC(acpi_force, "Force ACPI to be used."); 696 697MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); 698MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors."); 699MODULE_LICENSE ("GPL"); 700 701late_initcall(powernow_init); 702module_exit(powernow_exit); 703