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