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