1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2004-2005 Bruno Ducrot 5 * Copyright (c) 2004 FUKUDA Nobuhiko <nfukuda@spa.is.uec.ac.jp> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * Many thanks to Nate Lawson for his helpful comments on this driver and 30 * to Jung-uk Kim for testing. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/param.h> 37 #include <sys/bus.h> 38 #include <sys/cpu.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/module.h> 42 #include <sys/pcpu.h> 43 #include <sys/systm.h> 44 45 #include <machine/pc/bios.h> 46 #include <machine/md_var.h> 47 #include <machine/specialreg.h> 48 #include <machine/cputypes.h> 49 #include <machine/vmparam.h> 50 #include <sys/rman.h> 51 52 #include <vm/vm.h> 53 #include <vm/pmap.h> 54 55 #include "cpufreq_if.h" 56 57 #define PN7_TYPE 0 58 #define PN8_TYPE 1 59 60 /* Flags for some hardware bugs. */ 61 #define A0_ERRATA 0x1 /* Bugs for the rev. A0 of Athlon (K7): 62 * Interrupts must be disabled and no half 63 * multipliers are allowed */ 64 #define PENDING_STUCK 0x2 /* With some buggy chipset and some newer AMD64 65 * processor (Rev. G?): 66 * the pending bit from the msr FIDVID_STATUS 67 * is set forever. No workaround :( */ 68 69 /* Legacy configuration via BIOS table PSB. */ 70 #define PSB_START 0 71 #define PSB_STEP 0x10 72 #define PSB_SIG "AMDK7PNOW!" 73 #define PSB_LEN 10 74 #define PSB_OFF 0 75 76 struct psb_header { 77 char signature[10]; 78 uint8_t version; 79 uint8_t flags; 80 uint16_t settlingtime; 81 uint8_t res1; 82 uint8_t numpst; 83 } __packed; 84 85 struct pst_header { 86 uint32_t cpuid; 87 uint8_t fsb; 88 uint8_t maxfid; 89 uint8_t startvid; 90 uint8_t numpstates; 91 } __packed; 92 93 /* 94 * MSRs and bits used by Powernow technology 95 */ 96 #define MSR_AMDK7_FIDVID_CTL 0xc0010041 97 #define MSR_AMDK7_FIDVID_STATUS 0xc0010042 98 99 /* Bitfields used by K7 */ 100 101 #define PN7_CTR_FID(x) ((x) & 0x1f) 102 #define PN7_CTR_VID(x) (((x) & 0x1f) << 8) 103 #define PN7_CTR_FIDC 0x00010000 104 #define PN7_CTR_VIDC 0x00020000 105 #define PN7_CTR_FIDCHRATIO 0x00100000 106 #define PN7_CTR_SGTC(x) (((uint64_t)(x) & 0x000fffff) << 32) 107 108 #define PN7_STA_CFID(x) ((x) & 0x1f) 109 #define PN7_STA_SFID(x) (((x) >> 8) & 0x1f) 110 #define PN7_STA_MFID(x) (((x) >> 16) & 0x1f) 111 #define PN7_STA_CVID(x) (((x) >> 32) & 0x1f) 112 #define PN7_STA_SVID(x) (((x) >> 40) & 0x1f) 113 #define PN7_STA_MVID(x) (((x) >> 48) & 0x1f) 114 115 /* ACPI ctr_val status register to powernow k7 configuration */ 116 #define ACPI_PN7_CTRL_TO_FID(x) ((x) & 0x1f) 117 #define ACPI_PN7_CTRL_TO_VID(x) (((x) >> 5) & 0x1f) 118 #define ACPI_PN7_CTRL_TO_SGTC(x) (((x) >> 10) & 0xffff) 119 120 /* Bitfields used by K8 */ 121 122 #define PN8_CTR_FID(x) ((x) & 0x3f) 123 #define PN8_CTR_VID(x) (((x) & 0x1f) << 8) 124 #define PN8_CTR_PENDING(x) (((x) & 1) << 32) 125 126 #define PN8_STA_CFID(x) ((x) & 0x3f) 127 #define PN8_STA_SFID(x) (((x) >> 8) & 0x3f) 128 #define PN8_STA_MFID(x) (((x) >> 16) & 0x3f) 129 #define PN8_STA_PENDING(x) (((x) >> 31) & 0x01) 130 #define PN8_STA_CVID(x) (((x) >> 32) & 0x1f) 131 #define PN8_STA_SVID(x) (((x) >> 40) & 0x1f) 132 #define PN8_STA_MVID(x) (((x) >> 48) & 0x1f) 133 134 /* Reserved1 to powernow k8 configuration */ 135 #define PN8_PSB_TO_RVO(x) ((x) & 0x03) 136 #define PN8_PSB_TO_IRT(x) (((x) >> 2) & 0x03) 137 #define PN8_PSB_TO_MVS(x) (((x) >> 4) & 0x03) 138 #define PN8_PSB_TO_BATT(x) (((x) >> 6) & 0x03) 139 140 /* ACPI ctr_val status register to powernow k8 configuration */ 141 #define ACPI_PN8_CTRL_TO_FID(x) ((x) & 0x3f) 142 #define ACPI_PN8_CTRL_TO_VID(x) (((x) >> 6) & 0x1f) 143 #define ACPI_PN8_CTRL_TO_VST(x) (((x) >> 11) & 0x1f) 144 #define ACPI_PN8_CTRL_TO_MVS(x) (((x) >> 18) & 0x03) 145 #define ACPI_PN8_CTRL_TO_PLL(x) (((x) >> 20) & 0x7f) 146 #define ACPI_PN8_CTRL_TO_RVO(x) (((x) >> 28) & 0x03) 147 #define ACPI_PN8_CTRL_TO_IRT(x) (((x) >> 30) & 0x03) 148 149 #define WRITE_FIDVID(fid, vid, ctrl) \ 150 wrmsr(MSR_AMDK7_FIDVID_CTL, \ 151 (((ctrl) << 32) | (1ULL << 16) | ((vid) << 8) | (fid))) 152 153 #define COUNT_OFF_IRT(irt) DELAY(10 * (1 << (irt))) 154 #define COUNT_OFF_VST(vst) DELAY(20 * (vst)) 155 156 #define FID_TO_VCO_FID(fid) \ 157 (((fid) < 8) ? (8 + ((fid) << 1)) : (fid)) 158 159 /* 160 * Divide each value by 10 to get the processor multiplier. 161 * Some of those tables are the same as the Linux powernow-k7 162 * implementation by Dave Jones. 163 */ 164 static int pn7_fid_to_mult[32] = { 165 110, 115, 120, 125, 50, 55, 60, 65, 166 70, 75, 80, 85, 90, 95, 100, 105, 167 30, 190, 40, 200, 130, 135, 140, 210, 168 150, 225, 160, 165, 170, 180, 0, 0, 169 }; 170 171 static int pn8_fid_to_mult[64] = { 172 40, 45, 50, 55, 60, 65, 70, 75, 173 80, 85, 90, 95, 100, 105, 110, 115, 174 120, 125, 130, 135, 140, 145, 150, 155, 175 160, 165, 170, 175, 180, 185, 190, 195, 176 200, 205, 210, 215, 220, 225, 230, 235, 177 240, 245, 250, 255, 260, 265, 270, 275, 178 280, 285, 290, 295, 300, 305, 310, 315, 179 320, 325, 330, 335, 340, 345, 350, 355, 180 }; 181 182 /* 183 * Units are in mV. 184 */ 185 /* Mobile VRM (K7) */ 186 static int pn7_mobile_vid_to_volts[] = { 187 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, 188 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, 189 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, 190 1075, 1050, 1025, 1000, 975, 950, 925, 0, 191 }; 192 /* Desktop VRM (K7) */ 193 static int pn7_desktop_vid_to_volts[] = { 194 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, 195 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, 196 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, 197 1075, 1050, 1025, 1000, 975, 950, 925, 0, 198 }; 199 /* Desktop and Mobile VRM (K8) */ 200 static int pn8_vid_to_volts[] = { 201 1550, 1525, 1500, 1475, 1450, 1425, 1400, 1375, 202 1350, 1325, 1300, 1275, 1250, 1225, 1200, 1175, 203 1150, 1125, 1100, 1075, 1050, 1025, 1000, 975, 204 950, 925, 900, 875, 850, 825, 800, 0, 205 }; 206 207 #define POWERNOW_MAX_STATES 16 208 209 struct powernow_state { 210 int freq; 211 int power; 212 int fid; 213 int vid; 214 }; 215 216 struct pn_softc { 217 device_t dev; 218 int pn_type; 219 struct powernow_state powernow_states[POWERNOW_MAX_STATES]; 220 u_int fsb; 221 u_int sgtc; 222 u_int vst; 223 u_int mvs; 224 u_int pll; 225 u_int rvo; 226 u_int irt; 227 int low; 228 int powernow_max_states; 229 u_int powernow_state; 230 u_int errata; 231 int *vid_to_volts; 232 }; 233 234 /* 235 * Offsets in struct cf_setting array for private values given by 236 * acpi_perf driver. 237 */ 238 #define PX_SPEC_CONTROL 0 239 #define PX_SPEC_STATUS 1 240 241 static void pn_identify(driver_t *driver, device_t parent); 242 static int pn_probe(device_t dev); 243 static int pn_attach(device_t dev); 244 static int pn_detach(device_t dev); 245 static int pn_set(device_t dev, const struct cf_setting *cf); 246 static int pn_get(device_t dev, struct cf_setting *cf); 247 static int pn_settings(device_t dev, struct cf_setting *sets, 248 int *count); 249 static int pn_type(device_t dev, int *type); 250 251 static device_method_t pn_methods[] = { 252 /* Device interface */ 253 DEVMETHOD(device_identify, pn_identify), 254 DEVMETHOD(device_probe, pn_probe), 255 DEVMETHOD(device_attach, pn_attach), 256 DEVMETHOD(device_detach, pn_detach), 257 258 /* cpufreq interface */ 259 DEVMETHOD(cpufreq_drv_set, pn_set), 260 DEVMETHOD(cpufreq_drv_get, pn_get), 261 DEVMETHOD(cpufreq_drv_settings, pn_settings), 262 DEVMETHOD(cpufreq_drv_type, pn_type), 263 {0, 0} 264 }; 265 266 static devclass_t pn_devclass; 267 static driver_t pn_driver = { 268 "powernow", 269 pn_methods, 270 sizeof(struct pn_softc), 271 }; 272 273 DRIVER_MODULE(powernow, cpu, pn_driver, pn_devclass, 0, 0); 274 275 static int 276 pn7_setfidvid(struct pn_softc *sc, int fid, int vid) 277 { 278 int cfid, cvid; 279 uint64_t status, ctl; 280 281 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 282 cfid = PN7_STA_CFID(status); 283 cvid = PN7_STA_CVID(status); 284 285 /* We're already at the requested level. */ 286 if (fid == cfid && vid == cvid) 287 return (0); 288 289 ctl = rdmsr(MSR_AMDK7_FIDVID_CTL) & PN7_CTR_FIDCHRATIO; 290 291 ctl |= PN7_CTR_FID(fid); 292 ctl |= PN7_CTR_VID(vid); 293 ctl |= PN7_CTR_SGTC(sc->sgtc); 294 295 if (sc->errata & A0_ERRATA) 296 disable_intr(); 297 298 if (pn7_fid_to_mult[fid] < pn7_fid_to_mult[cfid]) { 299 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_FIDC); 300 if (vid != cvid) 301 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_VIDC); 302 } else { 303 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_VIDC); 304 if (fid != cfid) 305 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_FIDC); 306 } 307 308 if (sc->errata & A0_ERRATA) 309 enable_intr(); 310 311 return (0); 312 } 313 314 static int 315 pn8_read_pending_wait(uint64_t *status) 316 { 317 int i = 10000; 318 319 do 320 *status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 321 while (PN8_STA_PENDING(*status) && --i); 322 323 return (i == 0 ? ENXIO : 0); 324 } 325 326 static int 327 pn8_write_fidvid(u_int fid, u_int vid, uint64_t ctrl, uint64_t *status) 328 { 329 int i = 100; 330 331 do 332 WRITE_FIDVID(fid, vid, ctrl); 333 while (pn8_read_pending_wait(status) && --i); 334 335 return (i == 0 ? ENXIO : 0); 336 } 337 338 static int 339 pn8_setfidvid(struct pn_softc *sc, int fid, int vid) 340 { 341 uint64_t status; 342 int cfid, cvid; 343 int rvo; 344 int rv; 345 u_int val; 346 347 rv = pn8_read_pending_wait(&status); 348 if (rv) 349 return (rv); 350 351 cfid = PN8_STA_CFID(status); 352 cvid = PN8_STA_CVID(status); 353 354 if (fid == cfid && vid == cvid) 355 return (0); 356 357 /* 358 * Phase 1: Raise core voltage to requested VID if frequency is 359 * going up. 360 */ 361 while (cvid > vid) { 362 val = cvid - (1 << sc->mvs); 363 rv = pn8_write_fidvid(cfid, (val > 0) ? val : 0, 1ULL, &status); 364 if (rv) { 365 sc->errata |= PENDING_STUCK; 366 return (rv); 367 } 368 cvid = PN8_STA_CVID(status); 369 COUNT_OFF_VST(sc->vst); 370 } 371 372 /* ... then raise to voltage + RVO (if required) */ 373 for (rvo = sc->rvo; rvo > 0 && cvid > 0; --rvo) { 374 /* XXX It's not clear from spec if we have to do that 375 * in 0.25 step or in MVS. Therefore do it as it's done 376 * under Linux */ 377 rv = pn8_write_fidvid(cfid, cvid - 1, 1ULL, &status); 378 if (rv) { 379 sc->errata |= PENDING_STUCK; 380 return (rv); 381 } 382 cvid = PN8_STA_CVID(status); 383 COUNT_OFF_VST(sc->vst); 384 } 385 386 /* Phase 2: change to requested core frequency */ 387 if (cfid != fid) { 388 u_int vco_fid, vco_cfid, fid_delta; 389 390 vco_fid = FID_TO_VCO_FID(fid); 391 vco_cfid = FID_TO_VCO_FID(cfid); 392 393 while (abs(vco_fid - vco_cfid) > 2) { 394 fid_delta = (vco_cfid & 1) ? 1 : 2; 395 if (fid > cfid) { 396 if (cfid > 7) 397 val = cfid + fid_delta; 398 else 399 val = FID_TO_VCO_FID(cfid) + fid_delta; 400 } else 401 val = cfid - fid_delta; 402 rv = pn8_write_fidvid(val, cvid, 403 sc->pll * (uint64_t) sc->fsb, 404 &status); 405 if (rv) { 406 sc->errata |= PENDING_STUCK; 407 return (rv); 408 } 409 cfid = PN8_STA_CFID(status); 410 COUNT_OFF_IRT(sc->irt); 411 412 vco_cfid = FID_TO_VCO_FID(cfid); 413 } 414 415 rv = pn8_write_fidvid(fid, cvid, 416 sc->pll * (uint64_t) sc->fsb, 417 &status); 418 if (rv) { 419 sc->errata |= PENDING_STUCK; 420 return (rv); 421 } 422 cfid = PN8_STA_CFID(status); 423 COUNT_OFF_IRT(sc->irt); 424 } 425 426 /* Phase 3: change to requested voltage */ 427 if (cvid != vid) { 428 rv = pn8_write_fidvid(cfid, vid, 1ULL, &status); 429 cvid = PN8_STA_CVID(status); 430 COUNT_OFF_VST(sc->vst); 431 } 432 433 /* Check if transition failed. */ 434 if (cfid != fid || cvid != vid) 435 rv = ENXIO; 436 437 return (rv); 438 } 439 440 static int 441 pn_set(device_t dev, const struct cf_setting *cf) 442 { 443 struct pn_softc *sc; 444 int fid, vid; 445 int i; 446 int rv; 447 448 if (cf == NULL) 449 return (EINVAL); 450 sc = device_get_softc(dev); 451 452 if (sc->errata & PENDING_STUCK) 453 return (ENXIO); 454 455 for (i = 0; i < sc->powernow_max_states; ++i) 456 if (CPUFREQ_CMP(sc->powernow_states[i].freq / 1000, cf->freq)) 457 break; 458 459 fid = sc->powernow_states[i].fid; 460 vid = sc->powernow_states[i].vid; 461 462 rv = ENODEV; 463 464 switch (sc->pn_type) { 465 case PN7_TYPE: 466 rv = pn7_setfidvid(sc, fid, vid); 467 break; 468 case PN8_TYPE: 469 rv = pn8_setfidvid(sc, fid, vid); 470 break; 471 } 472 473 return (rv); 474 } 475 476 static int 477 pn_get(device_t dev, struct cf_setting *cf) 478 { 479 struct pn_softc *sc; 480 u_int cfid = 0, cvid = 0; 481 int i; 482 uint64_t status; 483 484 if (cf == NULL) 485 return (EINVAL); 486 sc = device_get_softc(dev); 487 if (sc->errata & PENDING_STUCK) 488 return (ENXIO); 489 490 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 491 492 switch (sc->pn_type) { 493 case PN7_TYPE: 494 cfid = PN7_STA_CFID(status); 495 cvid = PN7_STA_CVID(status); 496 break; 497 case PN8_TYPE: 498 cfid = PN8_STA_CFID(status); 499 cvid = PN8_STA_CVID(status); 500 break; 501 } 502 for (i = 0; i < sc->powernow_max_states; ++i) 503 if (cfid == sc->powernow_states[i].fid && 504 cvid == sc->powernow_states[i].vid) 505 break; 506 507 if (i < sc->powernow_max_states) { 508 cf->freq = sc->powernow_states[i].freq / 1000; 509 cf->power = sc->powernow_states[i].power; 510 cf->lat = 200; 511 cf->volts = sc->vid_to_volts[cvid]; 512 cf->dev = dev; 513 } else { 514 memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf)); 515 cf->dev = NULL; 516 } 517 518 return (0); 519 } 520 521 static int 522 pn_settings(device_t dev, struct cf_setting *sets, int *count) 523 { 524 struct pn_softc *sc; 525 int i; 526 527 if (sets == NULL|| count == NULL) 528 return (EINVAL); 529 sc = device_get_softc(dev); 530 if (*count < sc->powernow_max_states) 531 return (E2BIG); 532 for (i = 0; i < sc->powernow_max_states; ++i) { 533 sets[i].freq = sc->powernow_states[i].freq / 1000; 534 sets[i].power = sc->powernow_states[i].power; 535 sets[i].lat = 200; 536 sets[i].volts = sc->vid_to_volts[sc->powernow_states[i].vid]; 537 sets[i].dev = dev; 538 } 539 *count = sc->powernow_max_states; 540 541 return (0); 542 } 543 544 static int 545 pn_type(device_t dev, int *type) 546 { 547 if (type == NULL) 548 return (EINVAL); 549 550 *type = CPUFREQ_TYPE_ABSOLUTE; 551 552 return (0); 553 } 554 555 /* 556 * Given a set of pair of fid/vid, and number of performance states, 557 * compute powernow_states via an insertion sort. 558 */ 559 static int 560 decode_pst(struct pn_softc *sc, uint8_t *p, int npstates) 561 { 562 int i, j, n; 563 struct powernow_state state; 564 565 for (i = 0; i < POWERNOW_MAX_STATES; ++i) 566 sc->powernow_states[i].freq = CPUFREQ_VAL_UNKNOWN; 567 568 for (n = 0, i = 0; i < npstates; ++i) { 569 state.fid = *p++; 570 state.vid = *p++; 571 state.power = CPUFREQ_VAL_UNKNOWN; 572 573 switch (sc->pn_type) { 574 case PN7_TYPE: 575 state.freq = 100 * pn7_fid_to_mult[state.fid] * sc->fsb; 576 if ((sc->errata & A0_ERRATA) && 577 (pn7_fid_to_mult[state.fid] % 10) == 5) 578 continue; 579 break; 580 case PN8_TYPE: 581 state.freq = 100 * pn8_fid_to_mult[state.fid] * sc->fsb; 582 break; 583 } 584 585 j = n; 586 while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) { 587 memcpy(&sc->powernow_states[j], 588 &sc->powernow_states[j - 1], 589 sizeof(struct powernow_state)); 590 --j; 591 } 592 memcpy(&sc->powernow_states[j], &state, 593 sizeof(struct powernow_state)); 594 ++n; 595 } 596 597 /* 598 * Fix powernow_max_states, if errata a0 give us less states 599 * than expected. 600 */ 601 sc->powernow_max_states = n; 602 603 if (bootverbose) 604 for (i = 0; i < sc->powernow_max_states; ++i) { 605 int fid = sc->powernow_states[i].fid; 606 int vid = sc->powernow_states[i].vid; 607 608 printf("powernow: %2i %8dkHz FID %02x VID %02x\n", 609 i, 610 sc->powernow_states[i].freq, 611 fid, 612 vid); 613 } 614 615 return (0); 616 } 617 618 static int 619 cpuid_is_k7(u_int cpuid) 620 { 621 622 switch (cpuid) { 623 case 0x760: 624 case 0x761: 625 case 0x762: 626 case 0x770: 627 case 0x771: 628 case 0x780: 629 case 0x781: 630 case 0x7a0: 631 return (TRUE); 632 } 633 return (FALSE); 634 } 635 636 static int 637 pn_decode_pst(device_t dev) 638 { 639 int maxpst; 640 struct pn_softc *sc; 641 u_int cpuid, maxfid, startvid; 642 u_long sig; 643 struct psb_header *psb; 644 uint8_t *p; 645 u_int regs[4]; 646 uint64_t status; 647 648 sc = device_get_softc(dev); 649 650 do_cpuid(0x80000001, regs); 651 cpuid = regs[0]; 652 653 if ((cpuid & 0xfff) == 0x760) 654 sc->errata |= A0_ERRATA; 655 656 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 657 658 switch (sc->pn_type) { 659 case PN7_TYPE: 660 maxfid = PN7_STA_MFID(status); 661 startvid = PN7_STA_SVID(status); 662 break; 663 case PN8_TYPE: 664 maxfid = PN8_STA_MFID(status); 665 /* 666 * we should actually use a variable named 'maxvid' if K8, 667 * but why introducing a new variable for that? 668 */ 669 startvid = PN8_STA_MVID(status); 670 break; 671 default: 672 return (ENODEV); 673 } 674 675 if (bootverbose) { 676 device_printf(dev, "STATUS: 0x%jx\n", status); 677 device_printf(dev, "STATUS: maxfid: 0x%02x\n", maxfid); 678 device_printf(dev, "STATUS: %s: 0x%02x\n", 679 sc->pn_type == PN7_TYPE ? "startvid" : "maxvid", 680 startvid); 681 } 682 683 sig = bios_sigsearch(PSB_START, PSB_SIG, PSB_LEN, PSB_STEP, PSB_OFF); 684 if (sig) { 685 struct pst_header *pst; 686 687 psb = (struct psb_header*)(uintptr_t)BIOS_PADDRTOVADDR(sig); 688 689 switch (psb->version) { 690 default: 691 return (ENODEV); 692 case 0x14: 693 /* 694 * We can't be picky about numpst since at least 695 * some systems have a value of 1 and some have 2. 696 * We trust that cpuid_is_k7() will be better at 697 * catching that we're on a K8 anyway. 698 */ 699 if (sc->pn_type != PN8_TYPE) 700 return (EINVAL); 701 sc->vst = psb->settlingtime; 702 sc->rvo = PN8_PSB_TO_RVO(psb->res1); 703 sc->irt = PN8_PSB_TO_IRT(psb->res1); 704 sc->mvs = PN8_PSB_TO_MVS(psb->res1); 705 sc->low = PN8_PSB_TO_BATT(psb->res1); 706 if (bootverbose) { 707 device_printf(dev, "PSB: VST: %d\n", 708 psb->settlingtime); 709 device_printf(dev, "PSB: RVO %x IRT %d " 710 "MVS %d BATT %d\n", 711 sc->rvo, 712 sc->irt, 713 sc->mvs, 714 sc->low); 715 } 716 break; 717 case 0x12: 718 if (sc->pn_type != PN7_TYPE) 719 return (EINVAL); 720 sc->sgtc = psb->settlingtime * sc->fsb; 721 if (sc->sgtc < 100 * sc->fsb) 722 sc->sgtc = 100 * sc->fsb; 723 break; 724 } 725 726 p = ((uint8_t *) psb) + sizeof(struct psb_header); 727 pst = (struct pst_header*) p; 728 729 maxpst = 200; 730 731 do { 732 struct pst_header *pst = (struct pst_header*) p; 733 734 if (cpuid == pst->cpuid && 735 maxfid == pst->maxfid && 736 startvid == pst->startvid) { 737 sc->powernow_max_states = pst->numpstates; 738 switch (sc->pn_type) { 739 case PN7_TYPE: 740 if (abs(sc->fsb - pst->fsb) > 5) 741 continue; 742 break; 743 case PN8_TYPE: 744 break; 745 } 746 return (decode_pst(sc, 747 p + sizeof(struct pst_header), 748 sc->powernow_max_states)); 749 } 750 751 p += sizeof(struct pst_header) + (2 * pst->numpstates); 752 } while (cpuid_is_k7(pst->cpuid) && maxpst--); 753 754 device_printf(dev, "no match for extended cpuid %.3x\n", cpuid); 755 } 756 757 return (ENODEV); 758 } 759 760 static int 761 pn_decode_acpi(device_t dev, device_t perf_dev) 762 { 763 int i, j, n; 764 uint64_t status; 765 uint32_t ctrl; 766 u_int cpuid; 767 u_int regs[4]; 768 struct pn_softc *sc; 769 struct powernow_state state; 770 struct cf_setting sets[POWERNOW_MAX_STATES]; 771 int count = POWERNOW_MAX_STATES; 772 int type; 773 int rv; 774 775 if (perf_dev == NULL) 776 return (ENXIO); 777 778 rv = CPUFREQ_DRV_SETTINGS(perf_dev, sets, &count); 779 if (rv) 780 return (ENXIO); 781 rv = CPUFREQ_DRV_TYPE(perf_dev, &type); 782 if (rv || (type & CPUFREQ_FLAG_INFO_ONLY) == 0) 783 return (ENXIO); 784 785 sc = device_get_softc(dev); 786 787 do_cpuid(0x80000001, regs); 788 cpuid = regs[0]; 789 if ((cpuid & 0xfff) == 0x760) 790 sc->errata |= A0_ERRATA; 791 792 ctrl = 0; 793 sc->sgtc = 0; 794 for (n = 0, i = 0; i < count; ++i) { 795 ctrl = sets[i].spec[PX_SPEC_CONTROL]; 796 switch (sc->pn_type) { 797 case PN7_TYPE: 798 state.fid = ACPI_PN7_CTRL_TO_FID(ctrl); 799 state.vid = ACPI_PN7_CTRL_TO_VID(ctrl); 800 if ((sc->errata & A0_ERRATA) && 801 (pn7_fid_to_mult[state.fid] % 10) == 5) 802 continue; 803 break; 804 case PN8_TYPE: 805 state.fid = ACPI_PN8_CTRL_TO_FID(ctrl); 806 state.vid = ACPI_PN8_CTRL_TO_VID(ctrl); 807 break; 808 } 809 state.freq = sets[i].freq * 1000; 810 state.power = sets[i].power; 811 812 j = n; 813 while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) { 814 memcpy(&sc->powernow_states[j], 815 &sc->powernow_states[j - 1], 816 sizeof(struct powernow_state)); 817 --j; 818 } 819 memcpy(&sc->powernow_states[j], &state, 820 sizeof(struct powernow_state)); 821 ++n; 822 } 823 824 sc->powernow_max_states = n; 825 state = sc->powernow_states[0]; 826 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 827 828 switch (sc->pn_type) { 829 case PN7_TYPE: 830 sc->sgtc = ACPI_PN7_CTRL_TO_SGTC(ctrl); 831 /* 832 * XXX Some bios forget the max frequency! 833 * This maybe indicates we have the wrong tables. Therefore, 834 * don't implement a quirk, but fallback to BIOS legacy 835 * tables instead. 836 */ 837 if (PN7_STA_MFID(status) != state.fid) { 838 device_printf(dev, "ACPI MAX frequency not found\n"); 839 return (EINVAL); 840 } 841 sc->fsb = state.freq / 100 / pn7_fid_to_mult[state.fid]; 842 break; 843 case PN8_TYPE: 844 sc->vst = ACPI_PN8_CTRL_TO_VST(ctrl), 845 sc->mvs = ACPI_PN8_CTRL_TO_MVS(ctrl), 846 sc->pll = ACPI_PN8_CTRL_TO_PLL(ctrl), 847 sc->rvo = ACPI_PN8_CTRL_TO_RVO(ctrl), 848 sc->irt = ACPI_PN8_CTRL_TO_IRT(ctrl); 849 sc->low = 0; /* XXX */ 850 851 /* 852 * powernow k8 supports only one low frequency. 853 */ 854 if (sc->powernow_max_states >= 2 && 855 (sc->powernow_states[sc->powernow_max_states - 2].fid < 8)) 856 return (EINVAL); 857 sc->fsb = state.freq / 100 / pn8_fid_to_mult[state.fid]; 858 break; 859 } 860 861 return (0); 862 } 863 864 static void 865 pn_identify(driver_t *driver, device_t parent) 866 { 867 868 if ((amd_pminfo & AMDPM_FID) == 0 || (amd_pminfo & AMDPM_VID) == 0) 869 return; 870 switch (cpu_id & 0xf00) { 871 case 0x600: 872 case 0xf00: 873 break; 874 default: 875 return; 876 } 877 if (device_find_child(parent, "powernow", -1) != NULL) 878 return; 879 if (BUS_ADD_CHILD(parent, 10, "powernow", device_get_unit(parent)) 880 == NULL) 881 device_printf(parent, "powernow: add child failed\n"); 882 } 883 884 static int 885 pn_probe(device_t dev) 886 { 887 struct pn_softc *sc; 888 uint64_t status; 889 uint64_t rate; 890 struct pcpu *pc; 891 u_int sfid, mfid, cfid; 892 893 sc = device_get_softc(dev); 894 sc->errata = 0; 895 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 896 897 pc = cpu_get_pcpu(dev); 898 if (pc == NULL) 899 return (ENODEV); 900 901 cpu_est_clockrate(pc->pc_cpuid, &rate); 902 903 switch (cpu_id & 0xf00) { 904 case 0x600: 905 sfid = PN7_STA_SFID(status); 906 mfid = PN7_STA_MFID(status); 907 cfid = PN7_STA_CFID(status); 908 sc->pn_type = PN7_TYPE; 909 sc->fsb = rate / 100000 / pn7_fid_to_mult[cfid]; 910 911 /* 912 * If start FID is different to max FID, then it is a 913 * mobile processor. If not, it is a low powered desktop 914 * processor. 915 */ 916 if (PN7_STA_SFID(status) != PN7_STA_MFID(status)) { 917 sc->vid_to_volts = pn7_mobile_vid_to_volts; 918 device_set_desc(dev, "PowerNow! K7"); 919 } else { 920 sc->vid_to_volts = pn7_desktop_vid_to_volts; 921 device_set_desc(dev, "Cool`n'Quiet K7"); 922 } 923 break; 924 925 case 0xf00: 926 sfid = PN8_STA_SFID(status); 927 mfid = PN8_STA_MFID(status); 928 cfid = PN8_STA_CFID(status); 929 sc->pn_type = PN8_TYPE; 930 sc->vid_to_volts = pn8_vid_to_volts; 931 sc->fsb = rate / 100000 / pn8_fid_to_mult[cfid]; 932 933 if (PN8_STA_SFID(status) != PN8_STA_MFID(status)) 934 device_set_desc(dev, "PowerNow! K8"); 935 else 936 device_set_desc(dev, "Cool`n'Quiet K8"); 937 break; 938 default: 939 return (ENODEV); 940 } 941 942 return (0); 943 } 944 945 static int 946 pn_attach(device_t dev) 947 { 948 int rv; 949 device_t child; 950 951 child = device_find_child(device_get_parent(dev), "acpi_perf", -1); 952 if (child) { 953 rv = pn_decode_acpi(dev, child); 954 if (rv) 955 rv = pn_decode_pst(dev); 956 } else 957 rv = pn_decode_pst(dev); 958 959 if (rv != 0) 960 return (ENXIO); 961 cpufreq_register(dev); 962 return (0); 963 } 964 965 static int 966 pn_detach(device_t dev) 967 { 968 969 return (cpufreq_unregister(dev)); 970 } 971