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 150 #define WRITE_FIDVID(fid, vid, ctrl) \ 151 wrmsr(MSR_AMDK7_FIDVID_CTL, \ 152 (((ctrl) << 32) | (1ULL << 16) | ((vid) << 8) | (fid))) 153 154 #define COUNT_OFF_IRT(irt) DELAY(10 * (1 << (irt))) 155 #define COUNT_OFF_VST(vst) DELAY(20 * (vst)) 156 157 #define FID_TO_VCO_FID(fid) \ 158 (((fid) < 8) ? (8 + ((fid) << 1)) : (fid)) 159 160 /* 161 * Divide each value by 10 to get the processor multiplier. 162 * Some of those tables are the same as the Linux powernow-k7 163 * implementation by Dave Jones. 164 */ 165 static int pn7_fid_to_mult[32] = { 166 110, 115, 120, 125, 50, 55, 60, 65, 167 70, 75, 80, 85, 90, 95, 100, 105, 168 30, 190, 40, 200, 130, 135, 140, 210, 169 150, 225, 160, 165, 170, 180, 0, 0, 170 }; 171 172 173 static int pn8_fid_to_mult[64] = { 174 40, 45, 50, 55, 60, 65, 70, 75, 175 80, 85, 90, 95, 100, 105, 110, 115, 176 120, 125, 130, 135, 140, 145, 150, 155, 177 160, 165, 170, 175, 180, 185, 190, 195, 178 200, 205, 210, 215, 220, 225, 230, 235, 179 240, 245, 250, 255, 260, 265, 270, 275, 180 280, 285, 290, 295, 300, 305, 310, 315, 181 320, 325, 330, 335, 340, 345, 350, 355, 182 }; 183 184 /* 185 * Units are in mV. 186 */ 187 /* Mobile VRM (K7) */ 188 static int pn7_mobile_vid_to_volts[] = { 189 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, 190 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, 191 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, 192 1075, 1050, 1025, 1000, 975, 950, 925, 0, 193 }; 194 /* Desktop VRM (K7) */ 195 static int pn7_desktop_vid_to_volts[] = { 196 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, 197 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, 198 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, 199 1075, 1050, 1025, 1000, 975, 950, 925, 0, 200 }; 201 /* Desktop and Mobile VRM (K8) */ 202 static int pn8_vid_to_volts[] = { 203 1550, 1525, 1500, 1475, 1450, 1425, 1400, 1375, 204 1350, 1325, 1300, 1275, 1250, 1225, 1200, 1175, 205 1150, 1125, 1100, 1075, 1050, 1025, 1000, 975, 206 950, 925, 900, 875, 850, 825, 800, 0, 207 }; 208 209 #define POWERNOW_MAX_STATES 16 210 211 struct powernow_state { 212 int freq; 213 int power; 214 int fid; 215 int vid; 216 }; 217 218 struct pn_softc { 219 device_t dev; 220 int pn_type; 221 struct powernow_state powernow_states[POWERNOW_MAX_STATES]; 222 u_int fsb; 223 u_int sgtc; 224 u_int vst; 225 u_int mvs; 226 u_int pll; 227 u_int rvo; 228 u_int irt; 229 int low; 230 int powernow_max_states; 231 u_int powernow_state; 232 u_int errata; 233 int *vid_to_volts; 234 }; 235 236 /* 237 * Offsets in struct cf_setting array for private values given by 238 * acpi_perf driver. 239 */ 240 #define PX_SPEC_CONTROL 0 241 #define PX_SPEC_STATUS 1 242 243 static void pn_identify(driver_t *driver, device_t parent); 244 static int pn_probe(device_t dev); 245 static int pn_attach(device_t dev); 246 static int pn_detach(device_t dev); 247 static int pn_set(device_t dev, const struct cf_setting *cf); 248 static int pn_get(device_t dev, struct cf_setting *cf); 249 static int pn_settings(device_t dev, struct cf_setting *sets, 250 int *count); 251 static int pn_type(device_t dev, int *type); 252 253 static device_method_t pn_methods[] = { 254 /* Device interface */ 255 DEVMETHOD(device_identify, pn_identify), 256 DEVMETHOD(device_probe, pn_probe), 257 DEVMETHOD(device_attach, pn_attach), 258 DEVMETHOD(device_detach, pn_detach), 259 260 /* cpufreq interface */ 261 DEVMETHOD(cpufreq_drv_set, pn_set), 262 DEVMETHOD(cpufreq_drv_get, pn_get), 263 DEVMETHOD(cpufreq_drv_settings, pn_settings), 264 DEVMETHOD(cpufreq_drv_type, pn_type), 265 266 {0, 0} 267 }; 268 269 static devclass_t pn_devclass; 270 static driver_t pn_driver = { 271 "powernow", 272 pn_methods, 273 sizeof(struct pn_softc), 274 }; 275 276 DRIVER_MODULE(powernow, cpu, pn_driver, pn_devclass, 0, 0); 277 278 static int 279 pn7_setfidvid(struct pn_softc *sc, int fid, int vid) 280 { 281 int cfid, cvid; 282 uint64_t status, ctl; 283 284 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 285 cfid = PN7_STA_CFID(status); 286 cvid = PN7_STA_CVID(status); 287 288 /* We're already at the requested level. */ 289 if (fid == cfid && vid == cvid) 290 return (0); 291 292 ctl = rdmsr(MSR_AMDK7_FIDVID_CTL) & PN7_CTR_FIDCHRATIO; 293 294 ctl |= PN7_CTR_FID(fid); 295 ctl |= PN7_CTR_VID(vid); 296 ctl |= PN7_CTR_SGTC(sc->sgtc); 297 298 if (sc->errata & A0_ERRATA) 299 disable_intr(); 300 301 if (pn7_fid_to_mult[fid] < pn7_fid_to_mult[cfid]) { 302 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_FIDC); 303 if (vid != cvid) 304 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_VIDC); 305 } else { 306 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_VIDC); 307 if (fid != cfid) 308 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_FIDC); 309 } 310 311 if (sc->errata & A0_ERRATA) 312 enable_intr(); 313 314 return (0); 315 } 316 317 static int 318 pn8_read_pending_wait(uint64_t *status) 319 { 320 int i = 10000; 321 322 do 323 *status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 324 while (PN8_STA_PENDING(*status) && --i); 325 326 return (i == 0 ? ENXIO : 0); 327 } 328 329 static int 330 pn8_write_fidvid(u_int fid, u_int vid, uint64_t ctrl, uint64_t *status) 331 { 332 int i = 100; 333 334 do 335 WRITE_FIDVID(fid, vid, ctrl); 336 while (pn8_read_pending_wait(status) && --i); 337 338 return (i == 0 ? ENXIO : 0); 339 } 340 341 static int 342 pn8_setfidvid(struct pn_softc *sc, int fid, int vid) 343 { 344 uint64_t status; 345 int cfid, cvid; 346 int rvo; 347 int rv; 348 u_int val; 349 350 rv = pn8_read_pending_wait(&status); 351 if (rv) 352 return (rv); 353 354 cfid = PN8_STA_CFID(status); 355 cvid = PN8_STA_CVID(status); 356 357 if (fid == cfid && vid == cvid) 358 return (0); 359 360 /* 361 * Phase 1: Raise core voltage to requested VID if frequency is 362 * going up. 363 */ 364 while (cvid > vid) { 365 val = cvid - (1 << sc->mvs); 366 rv = pn8_write_fidvid(cfid, (val > 0) ? val : 0, 1ULL, &status); 367 if (rv) { 368 sc->errata |= PENDING_STUCK; 369 return (rv); 370 } 371 cvid = PN8_STA_CVID(status); 372 COUNT_OFF_VST(sc->vst); 373 } 374 375 /* ... then raise to voltage + RVO (if required) */ 376 for (rvo = sc->rvo; rvo > 0 && cvid > 0; --rvo) { 377 /* XXX It's not clear from spec if we have to do that 378 * in 0.25 step or in MVS. Therefore do it as it's done 379 * under Linux */ 380 rv = pn8_write_fidvid(cfid, cvid - 1, 1ULL, &status); 381 if (rv) { 382 sc->errata |= PENDING_STUCK; 383 return (rv); 384 } 385 cvid = PN8_STA_CVID(status); 386 COUNT_OFF_VST(sc->vst); 387 } 388 389 /* Phase 2: change to requested core frequency */ 390 if (cfid != fid) { 391 u_int vco_fid, vco_cfid, fid_delta; 392 393 vco_fid = FID_TO_VCO_FID(fid); 394 vco_cfid = FID_TO_VCO_FID(cfid); 395 396 while (abs(vco_fid - vco_cfid) > 2) { 397 fid_delta = (vco_cfid & 1) ? 1 : 2; 398 if (fid > cfid) { 399 if (cfid > 7) 400 val = cfid + fid_delta; 401 else 402 val = FID_TO_VCO_FID(cfid) + fid_delta; 403 } else 404 val = cfid - fid_delta; 405 rv = pn8_write_fidvid(val, cvid, 406 sc->pll * (uint64_t) sc->fsb, 407 &status); 408 if (rv) { 409 sc->errata |= PENDING_STUCK; 410 return (rv); 411 } 412 cfid = PN8_STA_CFID(status); 413 COUNT_OFF_IRT(sc->irt); 414 415 vco_cfid = FID_TO_VCO_FID(cfid); 416 } 417 418 rv = pn8_write_fidvid(fid, cvid, 419 sc->pll * (uint64_t) sc->fsb, 420 &status); 421 if (rv) { 422 sc->errata |= PENDING_STUCK; 423 return (rv); 424 } 425 cfid = PN8_STA_CFID(status); 426 COUNT_OFF_IRT(sc->irt); 427 } 428 429 /* Phase 3: change to requested voltage */ 430 if (cvid != vid) { 431 rv = pn8_write_fidvid(cfid, vid, 1ULL, &status); 432 cvid = PN8_STA_CVID(status); 433 COUNT_OFF_VST(sc->vst); 434 } 435 436 /* Check if transition failed. */ 437 if (cfid != fid || cvid != vid) 438 rv = ENXIO; 439 440 return (rv); 441 } 442 443 static int 444 pn_set(device_t dev, const struct cf_setting *cf) 445 { 446 struct pn_softc *sc; 447 int fid, vid; 448 int i; 449 int rv; 450 451 if (cf == NULL) 452 return (EINVAL); 453 sc = device_get_softc(dev); 454 455 if (sc->errata & PENDING_STUCK) 456 return (ENXIO); 457 458 for (i = 0; i < sc->powernow_max_states; ++i) 459 if (CPUFREQ_CMP(sc->powernow_states[i].freq / 1000, cf->freq)) 460 break; 461 462 fid = sc->powernow_states[i].fid; 463 vid = sc->powernow_states[i].vid; 464 465 rv = ENODEV; 466 467 switch (sc->pn_type) { 468 case PN7_TYPE: 469 rv = pn7_setfidvid(sc, fid, vid); 470 break; 471 case PN8_TYPE: 472 rv = pn8_setfidvid(sc, fid, vid); 473 break; 474 } 475 476 return (rv); 477 } 478 479 static int 480 pn_get(device_t dev, struct cf_setting *cf) 481 { 482 struct pn_softc *sc; 483 u_int cfid = 0, cvid = 0; 484 int i; 485 uint64_t status; 486 487 if (cf == NULL) 488 return (EINVAL); 489 sc = device_get_softc(dev); 490 if (sc->errata & PENDING_STUCK) 491 return (ENXIO); 492 493 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 494 495 switch (sc->pn_type) { 496 case PN7_TYPE: 497 cfid = PN7_STA_CFID(status); 498 cvid = PN7_STA_CVID(status); 499 break; 500 case PN8_TYPE: 501 cfid = PN8_STA_CFID(status); 502 cvid = PN8_STA_CVID(status); 503 break; 504 } 505 for (i = 0; i < sc->powernow_max_states; ++i) 506 if (cfid == sc->powernow_states[i].fid && 507 cvid == sc->powernow_states[i].vid) 508 break; 509 510 if (i < sc->powernow_max_states) { 511 cf->freq = sc->powernow_states[i].freq / 1000; 512 cf->power = sc->powernow_states[i].power; 513 cf->lat = 200; 514 cf->volts = sc->vid_to_volts[cvid]; 515 cf->dev = dev; 516 } else { 517 memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf)); 518 cf->dev = NULL; 519 } 520 521 return (0); 522 } 523 524 static int 525 pn_settings(device_t dev, struct cf_setting *sets, int *count) 526 { 527 struct pn_softc *sc; 528 int i; 529 530 if (sets == NULL|| count == NULL) 531 return (EINVAL); 532 sc = device_get_softc(dev); 533 if (*count < sc->powernow_max_states) 534 return (E2BIG); 535 for (i = 0; i < sc->powernow_max_states; ++i) { 536 sets[i].freq = sc->powernow_states[i].freq / 1000; 537 sets[i].power = sc->powernow_states[i].power; 538 sets[i].lat = 200; 539 sets[i].volts = sc->vid_to_volts[sc->powernow_states[i].vid]; 540 sets[i].dev = dev; 541 } 542 *count = sc->powernow_max_states; 543 544 return (0); 545 } 546 547 static int 548 pn_type(device_t dev, int *type) 549 { 550 if (type == NULL) 551 return (EINVAL); 552 553 *type = CPUFREQ_TYPE_ABSOLUTE; 554 555 return (0); 556 } 557 558 /* 559 * Given a set of pair of fid/vid, and number of performance states, 560 * compute powernow_states via an insertion sort. 561 */ 562 static int 563 decode_pst(struct pn_softc *sc, uint8_t *p, int npstates) 564 { 565 int i, j, n; 566 struct powernow_state state; 567 568 for (i = 0; i < POWERNOW_MAX_STATES; ++i) 569 sc->powernow_states[i].freq = CPUFREQ_VAL_UNKNOWN; 570 571 for (n = 0, i = 0; i < npstates; ++i) { 572 state.fid = *p++; 573 state.vid = *p++; 574 state.power = CPUFREQ_VAL_UNKNOWN; 575 576 switch (sc->pn_type) { 577 case PN7_TYPE: 578 state.freq = 100 * pn7_fid_to_mult[state.fid] * sc->fsb; 579 if ((sc->errata & A0_ERRATA) && 580 (pn7_fid_to_mult[state.fid] % 10) == 5) 581 continue; 582 break; 583 case PN8_TYPE: 584 state.freq = 100 * pn8_fid_to_mult[state.fid] * sc->fsb; 585 break; 586 } 587 588 j = n; 589 while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) { 590 memcpy(&sc->powernow_states[j], 591 &sc->powernow_states[j - 1], 592 sizeof(struct powernow_state)); 593 --j; 594 } 595 memcpy(&sc->powernow_states[j], &state, 596 sizeof(struct powernow_state)); 597 ++n; 598 } 599 600 /* 601 * Fix powernow_max_states, if errata a0 give us less states 602 * than expected. 603 */ 604 sc->powernow_max_states = n; 605 606 if (bootverbose) 607 for (i = 0; i < sc->powernow_max_states; ++i) { 608 int fid = sc->powernow_states[i].fid; 609 int vid = sc->powernow_states[i].vid; 610 611 printf("powernow: %2i %8dkHz FID %02x VID %02x\n", 612 i, 613 sc->powernow_states[i].freq, 614 fid, 615 vid); 616 } 617 618 return (0); 619 } 620 621 static int 622 cpuid_is_k7(u_int cpuid) 623 { 624 625 switch (cpuid) { 626 case 0x760: 627 case 0x761: 628 case 0x762: 629 case 0x770: 630 case 0x771: 631 case 0x780: 632 case 0x781: 633 case 0x7a0: 634 return (TRUE); 635 } 636 return (FALSE); 637 } 638 639 static int 640 pn_decode_pst(device_t dev) 641 { 642 int maxpst; 643 struct pn_softc *sc; 644 u_int cpuid, maxfid, startvid; 645 u_long sig; 646 struct psb_header *psb; 647 uint8_t *p; 648 u_int regs[4]; 649 uint64_t status; 650 651 sc = device_get_softc(dev); 652 653 do_cpuid(0x80000001, regs); 654 cpuid = regs[0]; 655 656 if ((cpuid & 0xfff) == 0x760) 657 sc->errata |= A0_ERRATA; 658 659 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 660 661 switch (sc->pn_type) { 662 case PN7_TYPE: 663 maxfid = PN7_STA_MFID(status); 664 startvid = PN7_STA_SVID(status); 665 break; 666 case PN8_TYPE: 667 maxfid = PN8_STA_MFID(status); 668 /* 669 * we should actually use a variable named 'maxvid' if K8, 670 * but why introducing a new variable for that? 671 */ 672 startvid = PN8_STA_MVID(status); 673 break; 674 default: 675 return (ENODEV); 676 } 677 678 if (bootverbose) { 679 device_printf(dev, "STATUS: 0x%jx\n", status); 680 device_printf(dev, "STATUS: maxfid: 0x%02x\n", maxfid); 681 device_printf(dev, "STATUS: %s: 0x%02x\n", 682 sc->pn_type == PN7_TYPE ? "startvid" : "maxvid", 683 startvid); 684 } 685 686 sig = bios_sigsearch(PSB_START, PSB_SIG, PSB_LEN, PSB_STEP, PSB_OFF); 687 if (sig) { 688 struct pst_header *pst; 689 690 psb = (struct psb_header*)(uintptr_t)BIOS_PADDRTOVADDR(sig); 691 692 switch (psb->version) { 693 default: 694 return (ENODEV); 695 case 0x14: 696 /* 697 * We can't be picky about numpst since at least 698 * some systems have a value of 1 and some have 2. 699 * We trust that cpuid_is_k7() will be better at 700 * catching that we're on a K8 anyway. 701 */ 702 if (sc->pn_type != PN8_TYPE) 703 return (EINVAL); 704 sc->vst = psb->settlingtime; 705 sc->rvo = PN8_PSB_TO_RVO(psb->res1); 706 sc->irt = PN8_PSB_TO_IRT(psb->res1); 707 sc->mvs = PN8_PSB_TO_MVS(psb->res1); 708 sc->low = PN8_PSB_TO_BATT(psb->res1); 709 if (bootverbose) { 710 device_printf(dev, "PSB: VST: %d\n", 711 psb->settlingtime); 712 device_printf(dev, "PSB: RVO %x IRT %d " 713 "MVS %d BATT %d\n", 714 sc->rvo, 715 sc->irt, 716 sc->mvs, 717 sc->low); 718 } 719 break; 720 case 0x12: 721 if (sc->pn_type != PN7_TYPE) 722 return (EINVAL); 723 sc->sgtc = psb->settlingtime * sc->fsb; 724 if (sc->sgtc < 100 * sc->fsb) 725 sc->sgtc = 100 * sc->fsb; 726 break; 727 } 728 729 p = ((uint8_t *) psb) + sizeof(struct psb_header); 730 pst = (struct pst_header*) p; 731 732 maxpst = 200; 733 734 do { 735 struct pst_header *pst = (struct pst_header*) p; 736 737 if (cpuid == pst->cpuid && 738 maxfid == pst->maxfid && 739 startvid == pst->startvid) { 740 sc->powernow_max_states = pst->numpstates; 741 switch (sc->pn_type) { 742 case PN7_TYPE: 743 if (abs(sc->fsb - pst->fsb) > 5) 744 continue; 745 break; 746 case PN8_TYPE: 747 break; 748 } 749 return (decode_pst(sc, 750 p + sizeof(struct pst_header), 751 sc->powernow_max_states)); 752 } 753 754 p += sizeof(struct pst_header) + (2 * pst->numpstates); 755 } while (cpuid_is_k7(pst->cpuid) && maxpst--); 756 757 device_printf(dev, "no match for extended cpuid %.3x\n", cpuid); 758 } 759 760 return (ENODEV); 761 } 762 763 static int 764 pn_decode_acpi(device_t dev, device_t perf_dev) 765 { 766 int i, j, n; 767 uint64_t status; 768 uint32_t ctrl; 769 u_int cpuid; 770 u_int regs[4]; 771 struct pn_softc *sc; 772 struct powernow_state state; 773 struct cf_setting sets[POWERNOW_MAX_STATES]; 774 int count = POWERNOW_MAX_STATES; 775 int type; 776 int rv; 777 778 if (perf_dev == NULL) 779 return (ENXIO); 780 781 rv = CPUFREQ_DRV_SETTINGS(perf_dev, sets, &count); 782 if (rv) 783 return (ENXIO); 784 rv = CPUFREQ_DRV_TYPE(perf_dev, &type); 785 if (rv || (type & CPUFREQ_FLAG_INFO_ONLY) == 0) 786 return (ENXIO); 787 788 sc = device_get_softc(dev); 789 790 do_cpuid(0x80000001, regs); 791 cpuid = regs[0]; 792 if ((cpuid & 0xfff) == 0x760) 793 sc->errata |= A0_ERRATA; 794 795 ctrl = 0; 796 sc->sgtc = 0; 797 for (n = 0, i = 0; i < count; ++i) { 798 ctrl = sets[i].spec[PX_SPEC_CONTROL]; 799 switch (sc->pn_type) { 800 case PN7_TYPE: 801 state.fid = ACPI_PN7_CTRL_TO_FID(ctrl); 802 state.vid = ACPI_PN7_CTRL_TO_VID(ctrl); 803 if ((sc->errata & A0_ERRATA) && 804 (pn7_fid_to_mult[state.fid] % 10) == 5) 805 continue; 806 break; 807 case PN8_TYPE: 808 state.fid = ACPI_PN8_CTRL_TO_FID(ctrl); 809 state.vid = ACPI_PN8_CTRL_TO_VID(ctrl); 810 break; 811 } 812 state.freq = sets[i].freq * 1000; 813 state.power = sets[i].power; 814 815 j = n; 816 while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) { 817 memcpy(&sc->powernow_states[j], 818 &sc->powernow_states[j - 1], 819 sizeof(struct powernow_state)); 820 --j; 821 } 822 memcpy(&sc->powernow_states[j], &state, 823 sizeof(struct powernow_state)); 824 ++n; 825 } 826 827 sc->powernow_max_states = n; 828 state = sc->powernow_states[0]; 829 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 830 831 switch (sc->pn_type) { 832 case PN7_TYPE: 833 sc->sgtc = ACPI_PN7_CTRL_TO_SGTC(ctrl); 834 /* 835 * XXX Some bios forget the max frequency! 836 * This maybe indicates we have the wrong tables. Therefore, 837 * don't implement a quirk, but fallback to BIOS legacy 838 * tables instead. 839 */ 840 if (PN7_STA_MFID(status) != state.fid) { 841 device_printf(dev, "ACPI MAX frequency not found\n"); 842 return (EINVAL); 843 } 844 sc->fsb = state.freq / 100 / pn7_fid_to_mult[state.fid]; 845 break; 846 case PN8_TYPE: 847 sc->vst = ACPI_PN8_CTRL_TO_VST(ctrl), 848 sc->mvs = ACPI_PN8_CTRL_TO_MVS(ctrl), 849 sc->pll = ACPI_PN8_CTRL_TO_PLL(ctrl), 850 sc->rvo = ACPI_PN8_CTRL_TO_RVO(ctrl), 851 sc->irt = ACPI_PN8_CTRL_TO_IRT(ctrl); 852 sc->low = 0; /* XXX */ 853 854 /* 855 * powernow k8 supports only one low frequency. 856 */ 857 if (sc->powernow_max_states >= 2 && 858 (sc->powernow_states[sc->powernow_max_states - 2].fid < 8)) 859 return (EINVAL); 860 sc->fsb = state.freq / 100 / pn8_fid_to_mult[state.fid]; 861 break; 862 } 863 864 return (0); 865 } 866 867 static void 868 pn_identify(driver_t *driver, device_t parent) 869 { 870 871 if ((amd_pminfo & AMDPM_FID) == 0 || (amd_pminfo & AMDPM_VID) == 0) 872 return; 873 switch (cpu_id & 0xf00) { 874 case 0x600: 875 case 0xf00: 876 break; 877 default: 878 return; 879 } 880 if (device_find_child(parent, "powernow", -1) != NULL) 881 return; 882 if (BUS_ADD_CHILD(parent, 10, "powernow", -1) == NULL) 883 device_printf(parent, "powernow: add child failed\n"); 884 } 885 886 static int 887 pn_probe(device_t dev) 888 { 889 struct pn_softc *sc; 890 uint64_t status; 891 uint64_t rate; 892 struct pcpu *pc; 893 u_int sfid, mfid, cfid; 894 895 sc = device_get_softc(dev); 896 sc->errata = 0; 897 status = rdmsr(MSR_AMDK7_FIDVID_STATUS); 898 899 pc = cpu_get_pcpu(dev); 900 if (pc == NULL) 901 return (ENODEV); 902 903 cpu_est_clockrate(pc->pc_cpuid, &rate); 904 905 switch (cpu_id & 0xf00) { 906 case 0x600: 907 sfid = PN7_STA_SFID(status); 908 mfid = PN7_STA_MFID(status); 909 cfid = PN7_STA_CFID(status); 910 sc->pn_type = PN7_TYPE; 911 sc->fsb = rate / 100000 / pn7_fid_to_mult[cfid]; 912 913 /* 914 * If start FID is different to max FID, then it is a 915 * mobile processor. If not, it is a low powered desktop 916 * processor. 917 */ 918 if (PN7_STA_SFID(status) != PN7_STA_MFID(status)) { 919 sc->vid_to_volts = pn7_mobile_vid_to_volts; 920 device_set_desc(dev, "PowerNow! K7"); 921 } else { 922 sc->vid_to_volts = pn7_desktop_vid_to_volts; 923 device_set_desc(dev, "Cool`n'Quiet K7"); 924 } 925 break; 926 927 case 0xf00: 928 sfid = PN8_STA_SFID(status); 929 mfid = PN8_STA_MFID(status); 930 cfid = PN8_STA_CFID(status); 931 sc->pn_type = PN8_TYPE; 932 sc->vid_to_volts = pn8_vid_to_volts; 933 sc->fsb = rate / 100000 / pn8_fid_to_mult[cfid]; 934 935 if (PN8_STA_SFID(status) != PN8_STA_MFID(status)) 936 device_set_desc(dev, "PowerNow! K8"); 937 else 938 device_set_desc(dev, "Cool`n'Quiet K8"); 939 break; 940 default: 941 return (ENODEV); 942 } 943 944 return (0); 945 } 946 947 static int 948 pn_attach(device_t dev) 949 { 950 int rv; 951 device_t child; 952 953 child = device_find_child(device_get_parent(dev), "acpi_perf", -1); 954 if (child) { 955 rv = pn_decode_acpi(dev, child); 956 if (rv) 957 rv = pn_decode_pst(dev); 958 } else 959 rv = pn_decode_pst(dev); 960 961 if (rv != 0) 962 return (ENXIO); 963 cpufreq_register(dev); 964 return (0); 965 } 966 967 static int 968 pn_detach(device_t dev) 969 { 970 971 return (cpufreq_unregister(dev)); 972 } 973