1 /* $NetBSD: acpi_cpu_pstate.c,v 1.51 2011/06/22 08:49:54 jruoho Exp $ */ 2 3 /*- 4 * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen@iki.fi> 5 * All rights reserved. 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 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.51 2011/06/22 08:49:54 jruoho Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/kmem.h> 34 #include <sys/xcall.h> 35 36 #include <dev/acpi/acpireg.h> 37 #include <dev/acpi/acpivar.h> 38 #include <dev/acpi/acpi_cpu.h> 39 40 #define _COMPONENT ACPI_BUS_COMPONENT 41 ACPI_MODULE_NAME ("acpi_cpu_pstate") 42 43 static ACPI_STATUS acpicpu_pstate_pss(struct acpicpu_softc *); 44 static ACPI_STATUS acpicpu_pstate_pss_add(struct acpicpu_pstate *, 45 ACPI_OBJECT *); 46 static ACPI_STATUS acpicpu_pstate_xpss(struct acpicpu_softc *); 47 static ACPI_STATUS acpicpu_pstate_xpss_add(struct acpicpu_pstate *, 48 ACPI_OBJECT *); 49 static ACPI_STATUS acpicpu_pstate_pct(struct acpicpu_softc *); 50 static ACPI_STATUS acpicpu_pstate_dep(struct acpicpu_softc *); 51 static int acpicpu_pstate_max(struct acpicpu_softc *); 52 static int acpicpu_pstate_min(struct acpicpu_softc *); 53 static void acpicpu_pstate_change(struct acpicpu_softc *); 54 static void acpicpu_pstate_reset(struct acpicpu_softc *); 55 static void acpicpu_pstate_bios(void); 56 static void acpicpu_pstate_set_xcall(void *, void *); 57 58 extern struct acpicpu_softc **acpicpu_sc; 59 60 void 61 acpicpu_pstate_attach(device_t self) 62 { 63 struct acpicpu_softc *sc = device_private(self); 64 const char *str; 65 ACPI_HANDLE tmp; 66 ACPI_STATUS rv; 67 68 rv = acpicpu_pstate_pss(sc); 69 70 if (ACPI_FAILURE(rv)) { 71 str = "_PSS"; 72 goto fail; 73 } 74 75 /* 76 * Append additional information from the extended _PSS, 77 * if available. Note that XPSS can not be used on Intel 78 * systems that use either _PDC or _OSC. From the XPSS 79 * method specification: 80 * 81 * "The platform must not require the use of the 82 * optional _PDC or _OSC methods to coordinate 83 * between the operating system and firmware for 84 * the purposes of enabling specific processor 85 * power management features or implementations." 86 */ 87 if (sc->sc_cap == 0) { 88 89 rv = acpicpu_pstate_xpss(sc); 90 91 if (ACPI_SUCCESS(rv)) 92 sc->sc_flags |= ACPICPU_FLAG_P_XPSS; 93 } 94 95 rv = acpicpu_pstate_pct(sc); 96 97 if (ACPI_FAILURE(rv)) { 98 str = "_PCT"; 99 goto fail; 100 } 101 102 /* 103 * The ACPI 3.0 and 4.0 specifications mandate three 104 * objects for P-states: _PSS, _PCT, and _PPC. A less 105 * strict wording is however used in the earlier 2.0 106 * standard, and some systems conforming to ACPI 2.0 107 * do not have _PPC, the method for dynamic maximum. 108 */ 109 rv = AcpiGetHandle(sc->sc_node->ad_handle, "_PPC", &tmp); 110 111 if (ACPI_FAILURE(rv)) 112 aprint_debug_dev(self, "_PPC missing\n"); 113 114 /* 115 * Carry out MD initialization. 116 */ 117 rv = acpicpu_md_pstate_init(sc); 118 119 if (rv != 0) { 120 rv = AE_SUPPORT; 121 goto fail; 122 } 123 124 /* 125 * Query the optional _PSD. 126 */ 127 rv = acpicpu_pstate_dep(sc); 128 129 if (ACPI_SUCCESS(rv)) 130 sc->sc_flags |= ACPICPU_FLAG_P_DEP; 131 132 sc->sc_flags |= ACPICPU_FLAG_P; 133 134 acpicpu_pstate_bios(); 135 acpicpu_pstate_reset(sc); 136 137 return; 138 139 fail: 140 switch (rv) { 141 142 case AE_NOT_FOUND: 143 return; 144 145 case AE_SUPPORT: 146 aprint_verbose_dev(self, "P-states not supported\n"); 147 return; 148 149 default: 150 aprint_error_dev(self, "failed to evaluate " 151 "%s: %s\n", str, AcpiFormatException(rv)); 152 } 153 } 154 155 void 156 acpicpu_pstate_detach(device_t self) 157 { 158 struct acpicpu_softc *sc = device_private(self); 159 size_t size; 160 161 if ((sc->sc_flags & ACPICPU_FLAG_P) == 0) 162 return; 163 164 (void)acpicpu_md_pstate_stop(); 165 166 size = sc->sc_pstate_count * sizeof(*sc->sc_pstate); 167 168 if (sc->sc_pstate != NULL) 169 kmem_free(sc->sc_pstate, size); 170 171 sc->sc_flags &= ~ACPICPU_FLAG_P; 172 } 173 174 void 175 acpicpu_pstate_start(device_t self) 176 { 177 struct acpicpu_softc *sc = device_private(self); 178 struct acpicpu_pstate *ps; 179 uint32_t i; 180 int rv; 181 182 rv = acpicpu_md_pstate_start(sc); 183 184 if (rv != 0) 185 goto fail; 186 187 /* 188 * Initialize the states to P0. 189 */ 190 for (i = 0, rv = ENXIO; i < sc->sc_pstate_count; i++) { 191 192 ps = &sc->sc_pstate[i]; 193 194 if (ps->ps_freq != 0) { 195 acpicpu_pstate_set(sc->sc_ci, ps->ps_freq); 196 return; 197 } 198 } 199 200 fail: 201 sc->sc_flags &= ~ACPICPU_FLAG_P; 202 aprint_error_dev(self, "failed to start P-states (err %d)\n", rv); 203 } 204 205 void 206 acpicpu_pstate_suspend(void *aux) 207 { 208 struct acpicpu_pstate *ps = NULL; 209 struct acpicpu_softc *sc; 210 struct cpu_info *ci; 211 device_t self = aux; 212 uint64_t xc; 213 int32_t i; 214 215 sc = device_private(self); 216 ci = sc->sc_ci; 217 218 /* 219 * Reset any dynamic limits. 220 */ 221 mutex_enter(&sc->sc_mtx); 222 acpicpu_pstate_reset(sc); 223 224 /* 225 * Following design notes for Windows, we set the highest 226 * P-state when entering any of the system sleep states. 227 * When resuming, the saved P-state will be restored. 228 * 229 * Microsoft Corporation: Windows Native Processor 230 * Performance Control. Version 1.1a, November, 2002. 231 */ 232 sc->sc_pstate_saved = sc->sc_pstate_current; 233 234 for (i = sc->sc_pstate_count - 1; i >= 0; i--) { 235 236 if (sc->sc_pstate[i].ps_freq != 0) { 237 ps = &sc->sc_pstate[i]; 238 break; 239 } 240 } 241 242 if (__predict_false(ps == NULL)) { 243 mutex_exit(&sc->sc_mtx); 244 return; 245 } 246 247 if (sc->sc_pstate_saved == ps->ps_freq) { 248 mutex_exit(&sc->sc_mtx); 249 return; 250 } 251 252 mutex_exit(&sc->sc_mtx); 253 254 xc = xc_unicast(0, acpicpu_pstate_set_xcall, &ps->ps_freq, NULL, ci); 255 xc_wait(xc); 256 } 257 258 void 259 acpicpu_pstate_resume(void *aux) 260 { 261 struct acpicpu_softc *sc; 262 device_t self = aux; 263 uint32_t freq; 264 uint64_t xc; 265 266 sc = device_private(self); 267 freq = sc->sc_pstate_saved; 268 269 xc = xc_unicast(0, acpicpu_pstate_set_xcall, &freq, NULL, sc->sc_ci); 270 xc_wait(xc); 271 } 272 273 void 274 acpicpu_pstate_callback(void *aux) 275 { 276 struct acpicpu_softc *sc; 277 device_t self = aux; 278 uint32_t freq; 279 uint64_t xc; 280 281 sc = device_private(self); 282 283 mutex_enter(&sc->sc_mtx); 284 acpicpu_pstate_change(sc); 285 286 freq = sc->sc_pstate[sc->sc_pstate_max].ps_freq; 287 288 if (sc->sc_pstate_saved == 0) 289 sc->sc_pstate_saved = sc->sc_pstate_current; 290 291 if (sc->sc_pstate_saved <= freq) { 292 freq = sc->sc_pstate_saved; 293 sc->sc_pstate_saved = 0; 294 } 295 296 mutex_exit(&sc->sc_mtx); 297 298 xc = xc_unicast(0, acpicpu_pstate_set_xcall, &freq, NULL, sc->sc_ci); 299 xc_wait(xc); 300 } 301 302 ACPI_STATUS 303 acpicpu_pstate_pss(struct acpicpu_softc *sc) 304 { 305 struct acpicpu_pstate *ps; 306 ACPI_OBJECT *obj; 307 ACPI_BUFFER buf; 308 ACPI_STATUS rv; 309 uint32_t count; 310 uint32_t i, j; 311 312 rv = acpi_eval_struct(sc->sc_node->ad_handle, "_PSS", &buf); 313 314 if (ACPI_FAILURE(rv)) 315 return rv; 316 317 obj = buf.Pointer; 318 319 if (obj->Type != ACPI_TYPE_PACKAGE) { 320 rv = AE_TYPE; 321 goto out; 322 } 323 324 sc->sc_pstate_count = obj->Package.Count; 325 326 if (sc->sc_pstate_count == 0) { 327 rv = AE_NOT_EXIST; 328 goto out; 329 } 330 331 if (sc->sc_pstate_count > ACPICPU_P_STATE_MAX) { 332 rv = AE_LIMIT; 333 goto out; 334 } 335 336 sc->sc_pstate = kmem_zalloc(sc->sc_pstate_count * 337 sizeof(struct acpicpu_pstate), KM_SLEEP); 338 339 if (sc->sc_pstate == NULL) { 340 rv = AE_NO_MEMORY; 341 goto out; 342 } 343 344 for (count = i = 0; i < sc->sc_pstate_count; i++) { 345 346 ps = &sc->sc_pstate[i]; 347 rv = acpicpu_pstate_pss_add(ps, &obj->Package.Elements[i]); 348 349 if (ACPI_FAILURE(rv)) { 350 aprint_error_dev(sc->sc_dev, "failed to add " 351 "P-state: %s\n", AcpiFormatException(rv)); 352 ps->ps_freq = 0; 353 continue; 354 } 355 356 for (j = 0; j < i; j++) { 357 358 if (ps->ps_freq >= sc->sc_pstate[j].ps_freq) { 359 ps->ps_freq = 0; 360 break; 361 } 362 } 363 364 if (ps->ps_freq != 0) 365 count++; 366 } 367 368 rv = (count != 0) ? AE_OK : AE_NOT_EXIST; 369 370 out: 371 if (buf.Pointer != NULL) 372 ACPI_FREE(buf.Pointer); 373 374 return rv; 375 } 376 377 static ACPI_STATUS 378 acpicpu_pstate_pss_add(struct acpicpu_pstate *ps, ACPI_OBJECT *obj) 379 { 380 ACPI_OBJECT *elm; 381 int i; 382 383 if (obj->Type != ACPI_TYPE_PACKAGE) 384 return AE_TYPE; 385 386 if (obj->Package.Count != 6) 387 return AE_BAD_DATA; 388 389 elm = obj->Package.Elements; 390 391 for (i = 0; i < 6; i++) { 392 393 if (elm[i].Type != ACPI_TYPE_INTEGER) 394 return AE_TYPE; 395 396 if (elm[i].Integer.Value > UINT32_MAX) 397 return AE_AML_NUMERIC_OVERFLOW; 398 } 399 400 ps->ps_freq = elm[0].Integer.Value; 401 ps->ps_power = elm[1].Integer.Value; 402 ps->ps_latency = elm[2].Integer.Value; 403 ps->ps_latency_bm = elm[3].Integer.Value; 404 ps->ps_control = elm[4].Integer.Value; 405 ps->ps_status = elm[5].Integer.Value; 406 407 if (ps->ps_freq == 0 || ps->ps_freq > 9999) 408 return AE_BAD_DECIMAL_CONSTANT; 409 410 if (ps->ps_latency == 0 || ps->ps_latency > 1000) 411 ps->ps_latency = 1; 412 413 return AE_OK; 414 } 415 416 static ACPI_STATUS 417 acpicpu_pstate_xpss(struct acpicpu_softc *sc) 418 { 419 struct acpicpu_pstate *ps; 420 ACPI_OBJECT *obj; 421 ACPI_BUFFER buf; 422 ACPI_STATUS rv; 423 uint32_t i = 0; 424 425 rv = acpi_eval_struct(sc->sc_node->ad_handle, "XPSS", &buf); 426 427 if (ACPI_FAILURE(rv)) 428 goto out; 429 430 obj = buf.Pointer; 431 432 if (obj->Type != ACPI_TYPE_PACKAGE) { 433 rv = AE_TYPE; 434 goto out; 435 } 436 437 if (obj->Package.Count != sc->sc_pstate_count) { 438 rv = AE_LIMIT; 439 goto out; 440 } 441 442 while (i < sc->sc_pstate_count) { 443 444 ps = &sc->sc_pstate[i]; 445 acpicpu_pstate_xpss_add(ps, &obj->Package.Elements[i]); 446 447 i++; 448 } 449 450 out: 451 if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND) 452 aprint_error_dev(sc->sc_dev, "failed to evaluate " 453 "XPSS: %s\n", AcpiFormatException(rv)); 454 455 if (buf.Pointer != NULL) 456 ACPI_FREE(buf.Pointer); 457 458 return rv; 459 } 460 461 static ACPI_STATUS 462 acpicpu_pstate_xpss_add(struct acpicpu_pstate *ps, ACPI_OBJECT *obj) 463 { 464 ACPI_OBJECT *elm; 465 int i; 466 467 if (obj->Type != ACPI_TYPE_PACKAGE) 468 return AE_TYPE; 469 470 if (obj->Package.Count != 8) 471 return AE_BAD_DATA; 472 473 elm = obj->Package.Elements; 474 475 for (i = 0; i < 4; i++) { 476 477 if (elm[i].Type != ACPI_TYPE_INTEGER) 478 return AE_TYPE; 479 480 if (elm[i].Integer.Value > UINT32_MAX) 481 return AE_AML_NUMERIC_OVERFLOW; 482 } 483 484 for (; i < 8; i++) { 485 486 if (elm[i].Type != ACPI_TYPE_BUFFER) 487 return AE_TYPE; 488 489 if (elm[i].Buffer.Length != 8) 490 return AE_LIMIT; 491 } 492 493 /* 494 * Only overwrite the elements that were 495 * not available from the conventional _PSS. 496 */ 497 if (ps->ps_freq == 0) 498 ps->ps_freq = elm[0].Integer.Value; 499 500 if (ps->ps_power == 0) 501 ps->ps_power = elm[1].Integer.Value; 502 503 if (ps->ps_latency == 0) 504 ps->ps_latency = elm[2].Integer.Value; 505 506 if (ps->ps_latency_bm == 0) 507 ps->ps_latency_bm = elm[3].Integer.Value; 508 509 if (ps->ps_control == 0) 510 ps->ps_control = ACPI_GET64(elm[4].Buffer.Pointer); 511 512 if (ps->ps_status == 0) 513 ps->ps_status = ACPI_GET64(elm[5].Buffer.Pointer); 514 515 if (ps->ps_control_mask == 0) 516 ps->ps_control_mask = ACPI_GET64(elm[6].Buffer.Pointer); 517 518 if (ps->ps_status_mask == 0) 519 ps->ps_status_mask = ACPI_GET64(elm[7].Buffer.Pointer); 520 521 ps->ps_flags |= ACPICPU_FLAG_P_XPSS; 522 523 if (ps->ps_freq == 0 || ps->ps_freq > 9999) 524 return AE_BAD_DECIMAL_CONSTANT; 525 526 if (ps->ps_latency == 0 || ps->ps_latency > 1000) 527 ps->ps_latency = 1; 528 529 return AE_OK; 530 } 531 532 ACPI_STATUS 533 acpicpu_pstate_pct(struct acpicpu_softc *sc) 534 { 535 static const size_t size = sizeof(struct acpicpu_reg); 536 struct acpicpu_reg *reg[2]; 537 struct acpicpu_pstate *ps; 538 ACPI_OBJECT *elm, *obj; 539 ACPI_BUFFER buf; 540 ACPI_STATUS rv; 541 uint8_t width; 542 uint32_t i; 543 544 rv = acpi_eval_struct(sc->sc_node->ad_handle, "_PCT", &buf); 545 546 if (ACPI_FAILURE(rv)) 547 return rv; 548 549 obj = buf.Pointer; 550 551 if (obj->Type != ACPI_TYPE_PACKAGE) { 552 rv = AE_TYPE; 553 goto out; 554 } 555 556 if (obj->Package.Count != 2) { 557 rv = AE_LIMIT; 558 goto out; 559 } 560 561 for (i = 0; i < 2; i++) { 562 563 elm = &obj->Package.Elements[i]; 564 565 if (elm->Type != ACPI_TYPE_BUFFER) { 566 rv = AE_TYPE; 567 goto out; 568 } 569 570 if (size > elm->Buffer.Length) { 571 rv = AE_AML_BAD_RESOURCE_LENGTH; 572 goto out; 573 } 574 575 reg[i] = (struct acpicpu_reg *)elm->Buffer.Pointer; 576 577 switch (reg[i]->reg_spaceid) { 578 579 case ACPI_ADR_SPACE_SYSTEM_IO: 580 581 if (reg[i]->reg_addr == 0) { 582 rv = AE_AML_ILLEGAL_ADDRESS; 583 goto out; 584 } 585 586 width = reg[i]->reg_bitwidth; 587 588 if (width + reg[i]->reg_bitoffset > 32) { 589 rv = AE_AML_BAD_RESOURCE_VALUE; 590 goto out; 591 } 592 593 if (width != 8 && width != 16 && width != 32) { 594 rv = AE_AML_BAD_RESOURCE_VALUE; 595 goto out; 596 } 597 598 break; 599 600 case ACPI_ADR_SPACE_FIXED_HARDWARE: 601 602 if ((sc->sc_flags & ACPICPU_FLAG_P_XPSS) != 0) { 603 604 if (reg[i]->reg_bitwidth != 64) { 605 rv = AE_AML_BAD_RESOURCE_VALUE; 606 goto out; 607 } 608 609 if (reg[i]->reg_bitoffset != 0) { 610 rv = AE_AML_BAD_RESOURCE_VALUE; 611 goto out; 612 } 613 614 break; 615 } 616 617 if ((sc->sc_flags & ACPICPU_FLAG_P_FFH) == 0) { 618 rv = AE_SUPPORT; 619 goto out; 620 } 621 622 break; 623 624 default: 625 rv = AE_AML_INVALID_SPACE_ID; 626 goto out; 627 } 628 } 629 630 if (reg[0]->reg_spaceid != reg[1]->reg_spaceid) { 631 rv = AE_AML_INVALID_SPACE_ID; 632 goto out; 633 } 634 635 (void)memcpy(&sc->sc_pstate_control, reg[0], size); 636 (void)memcpy(&sc->sc_pstate_status, reg[1], size); 637 638 if ((sc->sc_flags & ACPICPU_FLAG_P_XPSS) == 0) 639 goto out; 640 641 /* 642 * At the very least, mandate that 643 * XPSS supplies the control address. 644 */ 645 if (sc->sc_pstate_control.reg_addr == 0) { 646 rv = AE_AML_BAD_RESOURCE_LENGTH; 647 goto out; 648 } 649 650 /* 651 * If XPSS is present, copy the MSR addresses 652 * to the P-state structures for convenience. 653 */ 654 for (i = 0; i < sc->sc_pstate_count; i++) { 655 656 ps = &sc->sc_pstate[i]; 657 658 if (ps->ps_freq == 0) 659 continue; 660 661 ps->ps_status_addr = sc->sc_pstate_status.reg_addr; 662 ps->ps_control_addr = sc->sc_pstate_control.reg_addr; 663 } 664 665 out: 666 if (buf.Pointer != NULL) 667 ACPI_FREE(buf.Pointer); 668 669 return rv; 670 } 671 672 static ACPI_STATUS 673 acpicpu_pstate_dep(struct acpicpu_softc *sc) 674 { 675 ACPI_OBJECT *elm, *obj; 676 ACPI_BUFFER buf; 677 ACPI_STATUS rv; 678 uint32_t val; 679 uint8_t i, n; 680 681 rv = acpi_eval_struct(sc->sc_node->ad_handle, "_PSD", &buf); 682 683 if (ACPI_FAILURE(rv)) 684 goto out; 685 686 obj = buf.Pointer; 687 688 if (obj->Type != ACPI_TYPE_PACKAGE) { 689 rv = AE_TYPE; 690 goto out; 691 } 692 693 if (obj->Package.Count != 1) { 694 rv = AE_LIMIT; 695 goto out; 696 } 697 698 elm = &obj->Package.Elements[0]; 699 700 if (obj->Type != ACPI_TYPE_PACKAGE) { 701 rv = AE_TYPE; 702 goto out; 703 } 704 705 n = elm->Package.Count; 706 707 if (n != 5) { 708 rv = AE_LIMIT; 709 goto out; 710 } 711 712 elm = elm->Package.Elements; 713 714 for (i = 0; i < n; i++) { 715 716 if (elm[i].Type != ACPI_TYPE_INTEGER) { 717 rv = AE_TYPE; 718 goto out; 719 } 720 721 if (elm[i].Integer.Value > UINT32_MAX) { 722 rv = AE_AML_NUMERIC_OVERFLOW; 723 goto out; 724 } 725 } 726 727 val = elm[1].Integer.Value; 728 729 if (val != 0) 730 aprint_debug_dev(sc->sc_dev, "invalid revision in _PSD\n"); 731 732 val = elm[3].Integer.Value; 733 734 if (val < ACPICPU_DEP_SW_ALL || val > ACPICPU_DEP_HW_ALL) { 735 rv = AE_AML_BAD_RESOURCE_VALUE; 736 goto out; 737 } 738 739 val = elm[4].Integer.Value; 740 741 if (val > sc->sc_ncpus) { 742 rv = AE_BAD_VALUE; 743 goto out; 744 } 745 746 sc->sc_pstate_dep.dep_domain = elm[2].Integer.Value; 747 sc->sc_pstate_dep.dep_type = elm[3].Integer.Value; 748 sc->sc_pstate_dep.dep_ncpus = elm[4].Integer.Value; 749 750 out: 751 if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND) 752 aprint_debug_dev(sc->sc_dev, "failed to evaluate " 753 "_PSD: %s\n", AcpiFormatException(rv)); 754 755 if (buf.Pointer != NULL) 756 ACPI_FREE(buf.Pointer); 757 758 return rv; 759 } 760 761 static int 762 acpicpu_pstate_max(struct acpicpu_softc *sc) 763 { 764 ACPI_INTEGER val; 765 ACPI_STATUS rv; 766 767 /* 768 * Evaluate the currently highest P-state that can be used. 769 * If available, we can use either this state or any lower 770 * power (i.e. higher numbered) state from the _PSS object. 771 * Note that the return value must match the _OST parameter. 772 */ 773 rv = acpi_eval_integer(sc->sc_node->ad_handle, "_PPC", &val); 774 775 if (ACPI_SUCCESS(rv) && val < sc->sc_pstate_count) { 776 777 if (sc->sc_pstate[val].ps_freq != 0) { 778 sc->sc_pstate_max = val; 779 return 0; 780 } 781 } 782 783 return 1; 784 } 785 786 static int 787 acpicpu_pstate_min(struct acpicpu_softc *sc) 788 { 789 ACPI_INTEGER val; 790 ACPI_STATUS rv; 791 792 /* 793 * The _PDL object defines the minimum when passive cooling 794 * is being performed. If available, we can use the returned 795 * state or any higher power (i.e. lower numbered) state. 796 */ 797 rv = acpi_eval_integer(sc->sc_node->ad_handle, "_PDL", &val); 798 799 if (ACPI_SUCCESS(rv) && val < sc->sc_pstate_count) { 800 801 if (sc->sc_pstate[val].ps_freq == 0) 802 return 1; 803 804 if (val >= sc->sc_pstate_max) { 805 sc->sc_pstate_min = val; 806 return 0; 807 } 808 } 809 810 return 1; 811 } 812 813 static void 814 acpicpu_pstate_change(struct acpicpu_softc *sc) 815 { 816 static ACPI_STATUS rv = AE_OK; 817 ACPI_OBJECT_LIST arg; 818 ACPI_OBJECT obj[2]; 819 static int val = 0; 820 821 acpicpu_pstate_reset(sc); 822 823 /* 824 * Cache the checks as the optional 825 * _PDL and _OST are rarely present. 826 */ 827 if (val == 0) 828 val = acpicpu_pstate_min(sc); 829 830 arg.Count = 2; 831 arg.Pointer = obj; 832 833 obj[0].Type = ACPI_TYPE_INTEGER; 834 obj[1].Type = ACPI_TYPE_INTEGER; 835 836 obj[0].Integer.Value = ACPICPU_P_NOTIFY; 837 obj[1].Integer.Value = acpicpu_pstate_max(sc); 838 839 if (ACPI_FAILURE(rv)) 840 return; 841 842 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "_OST", &arg, NULL); 843 } 844 845 static void 846 acpicpu_pstate_reset(struct acpicpu_softc *sc) 847 { 848 849 sc->sc_pstate_max = 0; 850 sc->sc_pstate_min = sc->sc_pstate_count - 1; 851 852 } 853 854 static void 855 acpicpu_pstate_bios(void) 856 { 857 const uint8_t val = AcpiGbl_FADT.PstateControl; 858 const uint32_t addr = AcpiGbl_FADT.SmiCommand; 859 860 if (addr == 0 || val == 0) 861 return; 862 863 (void)AcpiOsWritePort(addr, val, 8); 864 } 865 866 int 867 acpicpu_pstate_get(struct cpu_info *ci, uint32_t *freq) 868 { 869 struct acpicpu_pstate *ps = NULL; 870 struct acpicpu_softc *sc; 871 uint32_t i, val = 0; 872 uint64_t addr; 873 uint8_t width; 874 int rv; 875 876 sc = acpicpu_sc[ci->ci_acpiid]; 877 878 if (__predict_false(sc == NULL)) { 879 rv = ENXIO; 880 goto fail; 881 } 882 883 if (__predict_false(sc->sc_cold != false)) { 884 rv = EBUSY; 885 goto fail; 886 } 887 888 if (__predict_false((sc->sc_flags & ACPICPU_FLAG_P) == 0)) { 889 rv = ENODEV; 890 goto fail; 891 } 892 893 mutex_enter(&sc->sc_mtx); 894 895 /* 896 * Use the cached value, if available. 897 */ 898 if (sc->sc_pstate_current != ACPICPU_P_STATE_UNKNOWN) { 899 *freq = sc->sc_pstate_current; 900 mutex_exit(&sc->sc_mtx); 901 return 0; 902 } 903 904 mutex_exit(&sc->sc_mtx); 905 906 switch (sc->sc_pstate_status.reg_spaceid) { 907 908 case ACPI_ADR_SPACE_FIXED_HARDWARE: 909 910 rv = acpicpu_md_pstate_get(sc, freq); 911 912 if (__predict_false(rv != 0)) 913 goto fail; 914 915 break; 916 917 case ACPI_ADR_SPACE_SYSTEM_IO: 918 919 addr = sc->sc_pstate_status.reg_addr; 920 width = sc->sc_pstate_status.reg_bitwidth; 921 922 (void)AcpiOsReadPort(addr, &val, width); 923 924 if (val == 0) { 925 rv = EIO; 926 goto fail; 927 } 928 929 for (i = 0; i < sc->sc_pstate_count; i++) { 930 931 if (sc->sc_pstate[i].ps_freq == 0) 932 continue; 933 934 if (val == sc->sc_pstate[i].ps_status) { 935 ps = &sc->sc_pstate[i]; 936 break; 937 } 938 } 939 940 if (ps == NULL) { 941 rv = EIO; 942 goto fail; 943 } 944 945 *freq = ps->ps_freq; 946 break; 947 948 default: 949 rv = ENOTTY; 950 goto fail; 951 } 952 953 mutex_enter(&sc->sc_mtx); 954 sc->sc_pstate_current = *freq; 955 mutex_exit(&sc->sc_mtx); 956 957 return 0; 958 959 fail: 960 aprint_error_dev(sc->sc_dev, "failed " 961 "to get frequency (err %d)\n", rv); 962 963 mutex_enter(&sc->sc_mtx); 964 *freq = sc->sc_pstate_current = ACPICPU_P_STATE_UNKNOWN; 965 mutex_exit(&sc->sc_mtx); 966 967 return rv; 968 } 969 970 void 971 acpicpu_pstate_set(struct cpu_info *ci, uint32_t freq) 972 { 973 uint64_t xc; 974 975 xc = xc_broadcast(0, acpicpu_pstate_set_xcall, &freq, NULL); 976 xc_wait(xc); 977 } 978 979 static void 980 acpicpu_pstate_set_xcall(void *arg1, void *arg2) 981 { 982 struct acpicpu_pstate *ps = NULL; 983 struct cpu_info *ci = curcpu(); 984 struct acpicpu_softc *sc; 985 uint32_t freq, i, val; 986 uint64_t addr; 987 uint8_t width; 988 int rv; 989 990 freq = *(uint32_t *)arg1; 991 sc = acpicpu_sc[ci->ci_acpiid]; 992 993 if (__predict_false(sc == NULL)) { 994 rv = ENXIO; 995 goto fail; 996 } 997 998 if (__predict_false(sc->sc_cold != false)) { 999 rv = EBUSY; 1000 goto fail; 1001 } 1002 1003 if (__predict_false((sc->sc_flags & ACPICPU_FLAG_P) == 0)) { 1004 rv = ENODEV; 1005 goto fail; 1006 } 1007 1008 mutex_enter(&sc->sc_mtx); 1009 1010 if (sc->sc_pstate_current == freq) { 1011 mutex_exit(&sc->sc_mtx); 1012 return; 1013 } 1014 1015 /* 1016 * Verify that the requested frequency is available. 1017 * 1018 * The access needs to be protected since the currently 1019 * available maximum and minimum may change dynamically. 1020 */ 1021 for (i = sc->sc_pstate_max; i <= sc->sc_pstate_min; i++) { 1022 1023 if (__predict_false(sc->sc_pstate[i].ps_freq == 0)) 1024 continue; 1025 1026 if (sc->sc_pstate[i].ps_freq == freq) { 1027 ps = &sc->sc_pstate[i]; 1028 break; 1029 } 1030 } 1031 1032 mutex_exit(&sc->sc_mtx); 1033 1034 if (__predict_false(ps == NULL)) { 1035 rv = EINVAL; 1036 goto fail; 1037 } 1038 1039 switch (sc->sc_pstate_control.reg_spaceid) { 1040 1041 case ACPI_ADR_SPACE_FIXED_HARDWARE: 1042 1043 rv = acpicpu_md_pstate_set(ps); 1044 1045 if (__predict_false(rv != 0)) 1046 goto fail; 1047 1048 break; 1049 1050 case ACPI_ADR_SPACE_SYSTEM_IO: 1051 1052 addr = sc->sc_pstate_control.reg_addr; 1053 width = sc->sc_pstate_control.reg_bitwidth; 1054 1055 (void)AcpiOsWritePort(addr, ps->ps_control, width); 1056 1057 addr = sc->sc_pstate_status.reg_addr; 1058 width = sc->sc_pstate_status.reg_bitwidth; 1059 1060 /* 1061 * Some systems take longer to respond 1062 * than the reported worst-case latency. 1063 */ 1064 for (i = val = 0; i < ACPICPU_P_STATE_RETRY; i++) { 1065 1066 (void)AcpiOsReadPort(addr, &val, width); 1067 1068 if (val == ps->ps_status) 1069 break; 1070 1071 DELAY(ps->ps_latency); 1072 } 1073 1074 if (i == ACPICPU_P_STATE_RETRY) { 1075 rv = EAGAIN; 1076 goto fail; 1077 } 1078 1079 break; 1080 1081 default: 1082 rv = ENOTTY; 1083 goto fail; 1084 } 1085 1086 mutex_enter(&sc->sc_mtx); 1087 ps->ps_evcnt.ev_count++; 1088 sc->sc_pstate_current = freq; 1089 mutex_exit(&sc->sc_mtx); 1090 1091 return; 1092 1093 fail: 1094 if (rv != EINVAL) 1095 aprint_error_dev(sc->sc_dev, "failed to set " 1096 "frequency to %u (err %d)\n", freq, rv); 1097 1098 mutex_enter(&sc->sc_mtx); 1099 sc->sc_pstate_current = ACPICPU_P_STATE_UNKNOWN; 1100 mutex_exit(&sc->sc_mtx); 1101 } 1102