1 /*- 2 * Copyright (C) 2013-2015 Daisuke Aoyama <aoyama@peach.ne.jp> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 #include <sys/param.h> 29 #include <sys/systm.h> 30 #include <sys/bus.h> 31 #include <sys/cpu.h> 32 #include <sys/kernel.h> 33 #include <sys/lock.h> 34 #include <sys/malloc.h> 35 #include <sys/module.h> 36 #include <sys/mutex.h> 37 #include <sys/sema.h> 38 #include <sys/sysctl.h> 39 40 #include <machine/bus.h> 41 #include <machine/cpu.h> 42 #include <machine/intr.h> 43 44 #include <dev/ofw/ofw_bus.h> 45 #include <dev/ofw/ofw_bus_subr.h> 46 47 #include <arm/broadcom/bcm2835/bcm2835_firmware.h> 48 #include <arm/broadcom/bcm2835/bcm2835_vcbus.h> 49 50 #include "cpufreq_if.h" 51 52 #ifdef DEBUG 53 #define DPRINTF(fmt, ...) do { \ 54 printf("%s:%u: ", __func__, __LINE__); \ 55 printf(fmt, ##__VA_ARGS__); \ 56 } while (0) 57 #else 58 #define DPRINTF(fmt, ...) 59 #endif 60 61 #define HZ2MHZ(freq) ((freq) / (1000 * 1000)) 62 #define MHZ2HZ(freq) ((freq) * (1000 * 1000)) 63 64 #define OFFSET2MVOLT(val) (((val) / 1000)) 65 #define MVOLT2OFFSET(val) (((val) * 1000)) 66 #define DEFAULT_ARM_FREQUENCY 600 67 #define DEFAULT_LOWEST_FREQ 600 68 #define DEFAULT_CORE_FREQUENCY 250 69 #define DEFAULT_SDRAM_FREQUENCY 400 70 #define TRANSITION_LATENCY 1000 71 #define MIN_OVER_VOLTAGE -16 72 #define MAX_OVER_VOLTAGE 6 73 #define MSG_ERROR -999999999 74 #define MHZSTEP 100 75 #define HZSTEP (MHZ2HZ(MHZSTEP)) 76 #define TZ_ZEROC 2731 77 78 #define VC_LOCK(sc) do { \ 79 sema_wait(&vc_sema); \ 80 } while (0) 81 #define VC_UNLOCK(sc) do { \ 82 sema_post(&vc_sema); \ 83 } while (0) 84 85 /* ARM->VC mailbox property semaphore */ 86 static struct sema vc_sema; 87 88 static struct sysctl_ctx_list bcm2835_sysctl_ctx; 89 90 struct bcm2835_cpufreq_softc { 91 device_t dev; 92 device_t firmware; 93 int arm_max_freq; 94 int arm_min_freq; 95 int core_max_freq; 96 int core_min_freq; 97 int sdram_max_freq; 98 int sdram_min_freq; 99 int max_voltage_core; 100 int min_voltage_core; 101 102 /* the values written in mbox */ 103 int voltage_core; 104 int voltage_sdram; 105 int voltage_sdram_c; 106 int voltage_sdram_i; 107 int voltage_sdram_p; 108 int turbo_mode; 109 110 /* initial hook for waiting mbox intr */ 111 struct intr_config_hook init_hook; 112 }; 113 114 static struct ofw_compat_data compat_data[] = { 115 { "broadcom,bcm2835-vc", 1 }, 116 { "broadcom,bcm2708-vc", 1 }, 117 { "brcm,bcm2709", 1 }, 118 { "brcm,bcm2835", 1 }, 119 { "brcm,bcm2836", 1 }, 120 { "brcm,bcm2837", 1 }, 121 { "brcm,bcm2711", 1 }, 122 { NULL, 0 } 123 }; 124 125 static int cpufreq_verbose = 0; 126 TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose); 127 static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ; 128 TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq); 129 130 #ifdef PROP_DEBUG 131 static void 132 bcm2835_dump(const void *data, int len) 133 { 134 const uint8_t *p = (const uint8_t*)data; 135 int i; 136 137 printf("dump @ %p:\n", data); 138 for (i = 0; i < len; i++) { 139 printf("%2.2x ", p[i]); 140 if ((i % 4) == 3) 141 printf(" "); 142 if ((i % 16) == 15) 143 printf("\n"); 144 } 145 printf("\n"); 146 } 147 #endif 148 149 static int 150 bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc, 151 uint32_t clock_id) 152 { 153 union msg_get_clock_rate_body msg; 154 int rate; 155 int err; 156 157 /* 158 * Get clock rate 159 * Tag: 0x00030002 160 * Request: 161 * Length: 4 162 * Value: 163 * u32: clock id 164 * Response: 165 * Length: 8 166 * Value: 167 * u32: clock id 168 * u32: rate (in Hz) 169 */ 170 171 /* setup single tag buffer */ 172 memset(&msg, 0, sizeof(msg)); 173 msg.req.clock_id = clock_id; 174 175 /* call mailbox property */ 176 err = bcm2835_firmware_property(sc->firmware, 177 BCM2835_FIRMWARE_TAG_GET_CLOCK_RATE, &msg, sizeof(msg)); 178 if (err) { 179 device_printf(sc->dev, "can't get clock rate (id=%u)\n", 180 clock_id); 181 return (MSG_ERROR); 182 } 183 184 /* result (Hz) */ 185 rate = (int)msg.resp.rate_hz; 186 DPRINTF("clock = %d(Hz)\n", rate); 187 return (rate); 188 } 189 190 static int 191 bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc, 192 uint32_t clock_id) 193 { 194 union msg_get_clock_rate_body msg; 195 int rate; 196 int err; 197 198 /* 199 * Get max clock rate 200 * Tag: 0x00030004 201 * Request: 202 * Length: 4 203 * Value: 204 * u32: clock id 205 * Response: 206 * Length: 8 207 * Value: 208 * u32: clock id 209 * u32: rate (in Hz) 210 */ 211 212 /* setup single tag buffer */ 213 memset(&msg, 0, sizeof(msg)); 214 msg.req.clock_id = clock_id; 215 216 /* call mailbox property */ 217 err = bcm2835_firmware_property(sc->firmware, 218 BCM2835_FIRMWARE_TAG_GET_MAX_CLOCK_RATE, &msg, sizeof(msg)); 219 if (err) { 220 device_printf(sc->dev, "can't get max clock rate (id=%u)\n", 221 clock_id); 222 return (MSG_ERROR); 223 } 224 225 /* result (Hz) */ 226 rate = (int)msg.resp.rate_hz; 227 DPRINTF("clock = %d(Hz)\n", rate); 228 return (rate); 229 } 230 231 static int 232 bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc, 233 uint32_t clock_id) 234 { 235 union msg_get_clock_rate_body msg; 236 int rate; 237 int err; 238 239 /* 240 * Get min clock rate 241 * Tag: 0x00030007 242 * Request: 243 * Length: 4 244 * Value: 245 * u32: clock id 246 * Response: 247 * Length: 8 248 * Value: 249 * u32: clock id 250 * u32: rate (in Hz) 251 */ 252 253 /* setup single tag buffer */ 254 memset(&msg, 0, sizeof(msg)); 255 msg.req.clock_id = clock_id; 256 257 /* call mailbox property */ 258 err = bcm2835_firmware_property(sc->firmware, 259 BCM2835_FIRMWARE_TAG_GET_MIN_CLOCK_RATE, &msg, sizeof(msg)); 260 if (err) { 261 device_printf(sc->dev, "can't get min clock rate (id=%u)\n", 262 clock_id); 263 return (MSG_ERROR); 264 } 265 266 /* result (Hz) */ 267 rate = (int)msg.resp.rate_hz; 268 DPRINTF("clock = %d(Hz)\n", rate); 269 return (rate); 270 } 271 272 static int 273 bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc, 274 uint32_t clock_id, uint32_t rate_hz) 275 { 276 union msg_set_clock_rate_body msg; 277 int rate; 278 int err; 279 280 /* 281 * Set clock rate 282 * Tag: 0x00038002 283 * Request: 284 * Length: 8 285 * Value: 286 * u32: clock id 287 * u32: rate (in Hz) 288 * Response: 289 * Length: 8 290 * Value: 291 * u32: clock id 292 * u32: rate (in Hz) 293 */ 294 295 /* setup single tag buffer */ 296 memset(&msg, 0, sizeof(msg)); 297 msg.req.clock_id = clock_id; 298 msg.req.rate_hz = rate_hz; 299 300 /* call mailbox property */ 301 err = bcm2835_firmware_property(sc->firmware, 302 BCM2835_FIRMWARE_TAG_SET_CLOCK_RATE, &msg, sizeof(msg)); 303 if (err) { 304 device_printf(sc->dev, "can't set clock rate (id=%u)\n", 305 clock_id); 306 return (MSG_ERROR); 307 } 308 309 /* workaround for core clock */ 310 if (clock_id == BCM2835_FIRMWARE_CLOCK_ID_CORE) { 311 /* for safety (may change voltage without changing clock) */ 312 DELAY(TRANSITION_LATENCY); 313 314 /* 315 * XXX: the core clock is unable to change at once, 316 * to change certainly, write it twice now. 317 */ 318 319 /* setup single tag buffer */ 320 memset(&msg, 0, sizeof(msg)); 321 msg.req.clock_id = clock_id; 322 msg.req.rate_hz = rate_hz; 323 324 /* call mailbox property */ 325 err = bcm2835_firmware_property(sc->firmware, 326 BCM2835_FIRMWARE_TAG_SET_CLOCK_RATE, &msg, sizeof(msg)); 327 if (err) { 328 device_printf(sc->dev, 329 "can't set clock rate (id=%u)\n", clock_id); 330 return (MSG_ERROR); 331 } 332 } 333 334 /* result (Hz) */ 335 rate = (int)msg.resp.rate_hz; 336 DPRINTF("clock = %d(Hz)\n", rate); 337 return (rate); 338 } 339 340 static int 341 bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc) 342 { 343 union msg_get_turbo_body msg; 344 int level; 345 int err; 346 347 /* 348 * Get turbo 349 * Tag: 0x00030009 350 * Request: 351 * Length: 4 352 * Value: 353 * u32: id 354 * Response: 355 * Length: 8 356 * Value: 357 * u32: id 358 * u32: level 359 */ 360 361 /* setup single tag buffer */ 362 memset(&msg, 0, sizeof(msg)); 363 msg.req.id = 0; 364 365 /* call mailbox property */ 366 err = bcm2835_firmware_property(sc->firmware, 367 BCM2835_FIRMWARE_TAG_GET_TURBO, &msg, sizeof(msg)); 368 if (err) { 369 device_printf(sc->dev, "can't get turbo\n"); 370 return (MSG_ERROR); 371 } 372 373 /* result 0=non-turbo, 1=turbo */ 374 level = (int)msg.resp.level; 375 DPRINTF("level = %d\n", level); 376 return (level); 377 } 378 379 static int 380 bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level) 381 { 382 union msg_set_turbo_body msg; 383 int value; 384 int err; 385 386 /* 387 * Set turbo 388 * Tag: 0x00038009 389 * Request: 390 * Length: 8 391 * Value: 392 * u32: id 393 * u32: level 394 * Response: 395 * Length: 8 396 * Value: 397 * u32: id 398 * u32: level 399 */ 400 401 /* replace unknown value to OFF */ 402 if (level != BCM2835_FIRMWARE_TURBO_ON && 403 level != BCM2835_FIRMWARE_TURBO_OFF) 404 level = BCM2835_FIRMWARE_TURBO_OFF; 405 406 /* setup single tag buffer */ 407 memset(&msg, 0, sizeof(msg)); 408 msg.req.id = 0; 409 msg.req.level = level; 410 411 /* call mailbox property */ 412 err = bcm2835_firmware_property(sc->firmware, 413 BCM2835_FIRMWARE_TAG_SET_TURBO, &msg, sizeof(msg)); 414 if (err) { 415 device_printf(sc->dev, "can't set turbo\n"); 416 return (MSG_ERROR); 417 } 418 419 /* result 0=non-turbo, 1=turbo */ 420 value = (int)msg.resp.level; 421 DPRINTF("level = %d\n", value); 422 return (value); 423 } 424 425 static int 426 bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc, 427 uint32_t voltage_id) 428 { 429 union msg_get_voltage_body msg; 430 int value; 431 int err; 432 433 /* 434 * Get voltage 435 * Tag: 0x00030003 436 * Request: 437 * Length: 4 438 * Value: 439 * u32: voltage id 440 * Response: 441 * Length: 8 442 * Value: 443 * u32: voltage id 444 * u32: value (offset from 1.2V in units of 0.025V) 445 */ 446 447 /* setup single tag buffer */ 448 memset(&msg, 0, sizeof(msg)); 449 msg.req.voltage_id = voltage_id; 450 451 /* call mailbox property */ 452 err = bcm2835_firmware_property(sc->firmware, 453 BCM2835_FIRMWARE_TAG_GET_VOLTAGE, &msg, sizeof(msg)); 454 if (err) { 455 device_printf(sc->dev, "can't get voltage\n"); 456 return (MSG_ERROR); 457 } 458 459 /* result (offset from 1.2V) */ 460 value = (int)msg.resp.value; 461 DPRINTF("value = %d\n", value); 462 return (value); 463 } 464 465 static int 466 bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc, 467 uint32_t voltage_id) 468 { 469 union msg_get_voltage_body msg; 470 int value; 471 int err; 472 473 /* 474 * Get voltage 475 * Tag: 0x00030005 476 * Request: 477 * Length: 4 478 * Value: 479 * u32: voltage id 480 * Response: 481 * Length: 8 482 * Value: 483 * u32: voltage id 484 * u32: value (offset from 1.2V in units of 0.025V) 485 */ 486 487 /* setup single tag buffer */ 488 memset(&msg, 0, sizeof(msg)); 489 msg.req.voltage_id = voltage_id; 490 491 /* call mailbox property */ 492 err = bcm2835_firmware_property(sc->firmware, 493 BCM2835_FIRMWARE_TAG_GET_MAX_VOLTAGE, &msg, sizeof(msg)); 494 if (err) { 495 device_printf(sc->dev, "can't get max voltage\n"); 496 return (MSG_ERROR); 497 } 498 499 /* result (offset from 1.2V) */ 500 value = (int)msg.resp.value; 501 DPRINTF("value = %d\n", value); 502 return (value); 503 } 504 static int 505 bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc, 506 uint32_t voltage_id) 507 { 508 union msg_get_voltage_body msg; 509 int value; 510 int err; 511 512 /* 513 * Get voltage 514 * Tag: 0x00030008 515 * Request: 516 * Length: 4 517 * Value: 518 * u32: voltage id 519 * Response: 520 * Length: 8 521 * Value: 522 * u32: voltage id 523 * u32: value (offset from 1.2V in units of 0.025V) 524 */ 525 526 /* setup single tag buffer */ 527 memset(&msg, 0, sizeof(msg)); 528 msg.req.voltage_id = voltage_id; 529 530 /* call mailbox property */ 531 err = bcm2835_firmware_property(sc->firmware, 532 BCM2835_FIRMWARE_TAG_GET_MIN_VOLTAGE, &msg, sizeof(msg)); 533 if (err) { 534 device_printf(sc->dev, "can't get min voltage\n"); 535 return (MSG_ERROR); 536 } 537 538 /* result (offset from 1.2V) */ 539 value = (int)msg.resp.value; 540 DPRINTF("value = %d\n", value); 541 return (value); 542 } 543 544 static int 545 bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc, 546 uint32_t voltage_id, int32_t value) 547 { 548 union msg_set_voltage_body msg; 549 int err; 550 551 /* 552 * Set voltage 553 * Tag: 0x00038003 554 * Request: 555 * Length: 4 556 * Value: 557 * u32: voltage id 558 * u32: value (offset from 1.2V in units of 0.025V) 559 * Response: 560 * Length: 8 561 * Value: 562 * u32: voltage id 563 * u32: value (offset from 1.2V in units of 0.025V) 564 */ 565 566 /* 567 * over_voltage: 568 * 0 (1.2 V). Values above 6 are only allowed when force_turbo or 569 * current_limit_override are specified (which set the warranty bit). 570 */ 571 if (value > MAX_OVER_VOLTAGE || value < MIN_OVER_VOLTAGE) { 572 /* currently not supported */ 573 device_printf(sc->dev, "not supported voltage: %d\n", value); 574 return (MSG_ERROR); 575 } 576 577 /* setup single tag buffer */ 578 memset(&msg, 0, sizeof(msg)); 579 msg.req.voltage_id = voltage_id; 580 msg.req.value = (uint32_t)value; 581 582 /* call mailbox property */ 583 err = bcm2835_firmware_property(sc->firmware, 584 BCM2835_FIRMWARE_TAG_SET_VOLTAGE, &msg, sizeof(msg)); 585 if (err) { 586 device_printf(sc->dev, "can't set voltage\n"); 587 return (MSG_ERROR); 588 } 589 590 /* result (offset from 1.2V) */ 591 value = (int)msg.resp.value; 592 DPRINTF("value = %d\n", value); 593 return (value); 594 } 595 596 static int 597 bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc) 598 { 599 union msg_get_temperature_body msg; 600 int value; 601 int err; 602 603 /* 604 * Get temperature 605 * Tag: 0x00030006 606 * Request: 607 * Length: 4 608 * Value: 609 * u32: temperature id 610 * Response: 611 * Length: 8 612 * Value: 613 * u32: temperature id 614 * u32: value 615 */ 616 617 /* setup single tag buffer */ 618 memset(&msg, 0, sizeof(msg)); 619 msg.req.temperature_id = 0; 620 621 /* call mailbox property */ 622 err = bcm2835_firmware_property(sc->firmware, 623 BCM2835_FIRMWARE_TAG_GET_TEMPERATURE, &msg, sizeof(msg)); 624 if (err) { 625 device_printf(sc->dev, "can't get temperature\n"); 626 return (MSG_ERROR); 627 } 628 629 /* result (temperature of degree C) */ 630 value = (int)msg.resp.value; 631 DPRINTF("value = %d\n", value); 632 return (value); 633 } 634 635 static int 636 sysctl_bcm2835_cpufreq_arm_freq(SYSCTL_HANDLER_ARGS) 637 { 638 struct bcm2835_cpufreq_softc *sc = arg1; 639 int val; 640 int err; 641 642 /* get realtime value */ 643 VC_LOCK(sc); 644 val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_FIRMWARE_CLOCK_ID_ARM); 645 VC_UNLOCK(sc); 646 if (val == MSG_ERROR) 647 return (EIO); 648 649 err = sysctl_handle_int(oidp, &val, 0, req); 650 if (err || !req->newptr) /* error || read request */ 651 return (err); 652 653 /* write request */ 654 VC_LOCK(sc); 655 err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_FIRMWARE_CLOCK_ID_ARM, 656 val); 657 VC_UNLOCK(sc); 658 if (err == MSG_ERROR) { 659 device_printf(sc->dev, "set clock arm_freq error\n"); 660 return (EIO); 661 } 662 DELAY(TRANSITION_LATENCY); 663 664 return (0); 665 } 666 667 static int 668 sysctl_bcm2835_cpufreq_core_freq(SYSCTL_HANDLER_ARGS) 669 { 670 struct bcm2835_cpufreq_softc *sc = arg1; 671 int val; 672 int err; 673 674 /* get realtime value */ 675 VC_LOCK(sc); 676 val = bcm2835_cpufreq_get_clock_rate(sc, 677 BCM2835_FIRMWARE_CLOCK_ID_CORE); 678 VC_UNLOCK(sc); 679 if (val == MSG_ERROR) 680 return (EIO); 681 682 err = sysctl_handle_int(oidp, &val, 0, req); 683 if (err || !req->newptr) /* error || read request */ 684 return (err); 685 686 /* write request */ 687 VC_LOCK(sc); 688 err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_FIRMWARE_CLOCK_ID_CORE, 689 val); 690 if (err == MSG_ERROR) { 691 VC_UNLOCK(sc); 692 device_printf(sc->dev, "set clock core_freq error\n"); 693 return (EIO); 694 } 695 VC_UNLOCK(sc); 696 DELAY(TRANSITION_LATENCY); 697 698 return (0); 699 } 700 701 static int 702 sysctl_bcm2835_cpufreq_sdram_freq(SYSCTL_HANDLER_ARGS) 703 { 704 struct bcm2835_cpufreq_softc *sc = arg1; 705 int val; 706 int err; 707 708 /* get realtime value */ 709 VC_LOCK(sc); 710 val = bcm2835_cpufreq_get_clock_rate(sc, 711 BCM2835_FIRMWARE_CLOCK_ID_SDRAM); 712 VC_UNLOCK(sc); 713 if (val == MSG_ERROR) 714 return (EIO); 715 716 err = sysctl_handle_int(oidp, &val, 0, req); 717 if (err || !req->newptr) /* error || read request */ 718 return (err); 719 720 /* write request */ 721 VC_LOCK(sc); 722 err = bcm2835_cpufreq_set_clock_rate(sc, 723 BCM2835_FIRMWARE_CLOCK_ID_SDRAM, val); 724 VC_UNLOCK(sc); 725 if (err == MSG_ERROR) { 726 device_printf(sc->dev, "set clock sdram_freq error\n"); 727 return (EIO); 728 } 729 DELAY(TRANSITION_LATENCY); 730 731 return (0); 732 } 733 734 static int 735 sysctl_bcm2835_cpufreq_turbo(SYSCTL_HANDLER_ARGS) 736 { 737 struct bcm2835_cpufreq_softc *sc = arg1; 738 int val; 739 int err; 740 741 /* get realtime value */ 742 VC_LOCK(sc); 743 val = bcm2835_cpufreq_get_turbo(sc); 744 VC_UNLOCK(sc); 745 if (val == MSG_ERROR) 746 return (EIO); 747 748 err = sysctl_handle_int(oidp, &val, 0, req); 749 if (err || !req->newptr) /* error || read request */ 750 return (err); 751 752 /* write request */ 753 if (val > 0) 754 sc->turbo_mode = BCM2835_FIRMWARE_TURBO_ON; 755 else 756 sc->turbo_mode = BCM2835_FIRMWARE_TURBO_OFF; 757 758 VC_LOCK(sc); 759 err = bcm2835_cpufreq_set_turbo(sc, sc->turbo_mode); 760 VC_UNLOCK(sc); 761 if (err == MSG_ERROR) { 762 device_printf(sc->dev, "set turbo error\n"); 763 return (EIO); 764 } 765 DELAY(TRANSITION_LATENCY); 766 767 return (0); 768 } 769 770 static int 771 sysctl_bcm2835_cpufreq_voltage_core(SYSCTL_HANDLER_ARGS) 772 { 773 struct bcm2835_cpufreq_softc *sc = arg1; 774 int val; 775 int err; 776 777 /* get realtime value */ 778 VC_LOCK(sc); 779 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_FIRMWARE_VOLTAGE_ID_CORE); 780 VC_UNLOCK(sc); 781 if (val == MSG_ERROR) 782 return (EIO); 783 784 err = sysctl_handle_int(oidp, &val, 0, req); 785 if (err || !req->newptr) /* error || read request */ 786 return (err); 787 788 /* write request */ 789 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) 790 return (EINVAL); 791 sc->voltage_core = val; 792 793 VC_LOCK(sc); 794 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_FIRMWARE_VOLTAGE_ID_CORE, 795 sc->voltage_core); 796 VC_UNLOCK(sc); 797 if (err == MSG_ERROR) { 798 device_printf(sc->dev, "set voltage core error\n"); 799 return (EIO); 800 } 801 DELAY(TRANSITION_LATENCY); 802 803 return (0); 804 } 805 806 static int 807 sysctl_bcm2835_cpufreq_voltage_sdram_c(SYSCTL_HANDLER_ARGS) 808 { 809 struct bcm2835_cpufreq_softc *sc = arg1; 810 int val; 811 int err; 812 813 /* get realtime value */ 814 VC_LOCK(sc); 815 val = bcm2835_cpufreq_get_voltage(sc, 816 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C); 817 VC_UNLOCK(sc); 818 if (val == MSG_ERROR) 819 return (EIO); 820 821 err = sysctl_handle_int(oidp, &val, 0, req); 822 if (err || !req->newptr) /* error || read request */ 823 return (err); 824 825 /* write request */ 826 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) 827 return (EINVAL); 828 sc->voltage_sdram_c = val; 829 830 VC_LOCK(sc); 831 err = bcm2835_cpufreq_set_voltage(sc, 832 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C, 833 sc->voltage_sdram_c); 834 VC_UNLOCK(sc); 835 if (err == MSG_ERROR) { 836 device_printf(sc->dev, "set voltage sdram_c error\n"); 837 return (EIO); 838 } 839 DELAY(TRANSITION_LATENCY); 840 841 return (0); 842 } 843 844 static int 845 sysctl_bcm2835_cpufreq_voltage_sdram_i(SYSCTL_HANDLER_ARGS) 846 { 847 struct bcm2835_cpufreq_softc *sc = arg1; 848 int val; 849 int err; 850 851 /* get realtime value */ 852 VC_LOCK(sc); 853 val = bcm2835_cpufreq_get_voltage(sc, 854 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I); 855 VC_UNLOCK(sc); 856 if (val == MSG_ERROR) 857 return (EIO); 858 859 err = sysctl_handle_int(oidp, &val, 0, req); 860 if (err || !req->newptr) /* error || read request */ 861 return (err); 862 863 /* write request */ 864 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) 865 return (EINVAL); 866 sc->voltage_sdram_i = val; 867 868 VC_LOCK(sc); 869 err = bcm2835_cpufreq_set_voltage(sc, 870 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I, sc->voltage_sdram_i); 871 VC_UNLOCK(sc); 872 if (err == MSG_ERROR) { 873 device_printf(sc->dev, "set voltage sdram_i error\n"); 874 return (EIO); 875 } 876 DELAY(TRANSITION_LATENCY); 877 878 return (0); 879 } 880 881 static int 882 sysctl_bcm2835_cpufreq_voltage_sdram_p(SYSCTL_HANDLER_ARGS) 883 { 884 struct bcm2835_cpufreq_softc *sc = arg1; 885 int val; 886 int err; 887 888 /* get realtime value */ 889 VC_LOCK(sc); 890 val = bcm2835_cpufreq_get_voltage(sc, 891 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P); 892 VC_UNLOCK(sc); 893 if (val == MSG_ERROR) 894 return (EIO); 895 896 err = sysctl_handle_int(oidp, &val, 0, req); 897 if (err || !req->newptr) /* error || read request */ 898 return (err); 899 900 /* write request */ 901 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) 902 return (EINVAL); 903 sc->voltage_sdram_p = val; 904 905 VC_LOCK(sc); 906 err = bcm2835_cpufreq_set_voltage(sc, 907 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P, sc->voltage_sdram_p); 908 VC_UNLOCK(sc); 909 if (err == MSG_ERROR) { 910 device_printf(sc->dev, "set voltage sdram_p error\n"); 911 return (EIO); 912 } 913 DELAY(TRANSITION_LATENCY); 914 915 return (0); 916 } 917 918 static int 919 sysctl_bcm2835_cpufreq_voltage_sdram(SYSCTL_HANDLER_ARGS) 920 { 921 struct bcm2835_cpufreq_softc *sc = arg1; 922 int val; 923 int err; 924 925 /* multiple write only */ 926 if (!req->newptr) 927 return (EINVAL); 928 val = 0; 929 err = sysctl_handle_int(oidp, &val, 0, req); 930 if (err) 931 return (err); 932 933 /* write request */ 934 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) 935 return (EINVAL); 936 sc->voltage_sdram = val; 937 938 VC_LOCK(sc); 939 err = bcm2835_cpufreq_set_voltage(sc, 940 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C, val); 941 if (err == MSG_ERROR) { 942 VC_UNLOCK(sc); 943 device_printf(sc->dev, "set voltage sdram_c error\n"); 944 return (EIO); 945 } 946 err = bcm2835_cpufreq_set_voltage(sc, 947 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I, val); 948 if (err == MSG_ERROR) { 949 VC_UNLOCK(sc); 950 device_printf(sc->dev, "set voltage sdram_i error\n"); 951 return (EIO); 952 } 953 err = bcm2835_cpufreq_set_voltage(sc, 954 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P, val); 955 if (err == MSG_ERROR) { 956 VC_UNLOCK(sc); 957 device_printf(sc->dev, "set voltage sdram_p error\n"); 958 return (EIO); 959 } 960 VC_UNLOCK(sc); 961 DELAY(TRANSITION_LATENCY); 962 963 return (0); 964 } 965 966 static int 967 sysctl_bcm2835_cpufreq_temperature(SYSCTL_HANDLER_ARGS) 968 { 969 struct bcm2835_cpufreq_softc *sc = arg1; 970 int val; 971 int err; 972 973 /* get realtime value */ 974 VC_LOCK(sc); 975 val = bcm2835_cpufreq_get_temperature(sc); 976 VC_UNLOCK(sc); 977 if (val == MSG_ERROR) 978 return (EIO); 979 980 err = sysctl_handle_int(oidp, &val, 0, req); 981 if (err || !req->newptr) /* error || read request */ 982 return (err); 983 984 /* write request */ 985 return (EINVAL); 986 } 987 988 static int 989 sysctl_bcm2835_devcpu_temperature(SYSCTL_HANDLER_ARGS) 990 { 991 struct bcm2835_cpufreq_softc *sc = arg1; 992 int val; 993 int err; 994 995 /* get realtime value */ 996 VC_LOCK(sc); 997 val = bcm2835_cpufreq_get_temperature(sc); 998 VC_UNLOCK(sc); 999 if (val == MSG_ERROR) 1000 return (EIO); 1001 1002 /* 1/1000 celsius (raw) to 1/10 kelvin */ 1003 val = val / 100 + TZ_ZEROC; 1004 1005 err = sysctl_handle_int(oidp, &val, 0, req); 1006 if (err || !req->newptr) /* error || read request */ 1007 return (err); 1008 1009 /* write request */ 1010 return (EINVAL); 1011 } 1012 1013 static void 1014 bcm2835_cpufreq_init(void *arg) 1015 { 1016 struct bcm2835_cpufreq_softc *sc = arg; 1017 struct sysctl_ctx_list *ctx; 1018 device_t cpu; 1019 int arm_freq, core_freq, sdram_freq; 1020 int arm_max_freq, arm_min_freq, core_max_freq, core_min_freq; 1021 int sdram_max_freq, sdram_min_freq; 1022 int voltage_core, voltage_sdram_c, voltage_sdram_i, voltage_sdram_p; 1023 int max_voltage_core, min_voltage_core; 1024 int max_voltage_sdram_c, min_voltage_sdram_c; 1025 int max_voltage_sdram_i, min_voltage_sdram_i; 1026 int max_voltage_sdram_p, min_voltage_sdram_p; 1027 int turbo, temperature; 1028 1029 VC_LOCK(sc); 1030 1031 /* current clock */ 1032 arm_freq = bcm2835_cpufreq_get_clock_rate(sc, 1033 BCM2835_FIRMWARE_CLOCK_ID_ARM); 1034 core_freq = bcm2835_cpufreq_get_clock_rate(sc, 1035 BCM2835_FIRMWARE_CLOCK_ID_CORE); 1036 sdram_freq = bcm2835_cpufreq_get_clock_rate(sc, 1037 BCM2835_FIRMWARE_CLOCK_ID_SDRAM); 1038 1039 /* max/min clock */ 1040 arm_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc, 1041 BCM2835_FIRMWARE_CLOCK_ID_ARM); 1042 arm_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc, 1043 BCM2835_FIRMWARE_CLOCK_ID_ARM); 1044 core_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc, 1045 BCM2835_FIRMWARE_CLOCK_ID_CORE); 1046 core_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc, 1047 BCM2835_FIRMWARE_CLOCK_ID_CORE); 1048 sdram_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc, 1049 BCM2835_FIRMWARE_CLOCK_ID_SDRAM); 1050 sdram_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc, 1051 BCM2835_FIRMWARE_CLOCK_ID_SDRAM); 1052 1053 /* turbo mode */ 1054 turbo = bcm2835_cpufreq_get_turbo(sc); 1055 if (turbo > 0) 1056 sc->turbo_mode = BCM2835_FIRMWARE_TURBO_ON; 1057 else 1058 sc->turbo_mode = BCM2835_FIRMWARE_TURBO_OFF; 1059 1060 /* voltage */ 1061 voltage_core = bcm2835_cpufreq_get_voltage(sc, 1062 BCM2835_FIRMWARE_VOLTAGE_ID_CORE); 1063 voltage_sdram_c = bcm2835_cpufreq_get_voltage(sc, 1064 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C); 1065 voltage_sdram_i = bcm2835_cpufreq_get_voltage(sc, 1066 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I); 1067 voltage_sdram_p = bcm2835_cpufreq_get_voltage(sc, 1068 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P); 1069 1070 /* current values (offset from 1.2V) */ 1071 sc->voltage_core = voltage_core; 1072 sc->voltage_sdram = voltage_sdram_c; 1073 sc->voltage_sdram_c = voltage_sdram_c; 1074 sc->voltage_sdram_i = voltage_sdram_i; 1075 sc->voltage_sdram_p = voltage_sdram_p; 1076 1077 /* max/min voltage */ 1078 max_voltage_core = bcm2835_cpufreq_get_max_voltage(sc, 1079 BCM2835_FIRMWARE_VOLTAGE_ID_CORE); 1080 min_voltage_core = bcm2835_cpufreq_get_min_voltage(sc, 1081 BCM2835_FIRMWARE_VOLTAGE_ID_CORE); 1082 max_voltage_sdram_c = bcm2835_cpufreq_get_max_voltage(sc, 1083 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C); 1084 max_voltage_sdram_i = bcm2835_cpufreq_get_max_voltage(sc, 1085 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I); 1086 max_voltage_sdram_p = bcm2835_cpufreq_get_max_voltage(sc, 1087 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P); 1088 min_voltage_sdram_c = bcm2835_cpufreq_get_min_voltage(sc, 1089 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C); 1090 min_voltage_sdram_i = bcm2835_cpufreq_get_min_voltage(sc, 1091 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I); 1092 min_voltage_sdram_p = bcm2835_cpufreq_get_min_voltage(sc, 1093 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P); 1094 1095 /* temperature */ 1096 temperature = bcm2835_cpufreq_get_temperature(sc); 1097 1098 /* show result */ 1099 if (cpufreq_verbose || bootverbose) { 1100 device_printf(sc->dev, "Boot settings:\n"); 1101 device_printf(sc->dev, 1102 "current ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n", 1103 HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq), 1104 (sc->turbo_mode == BCM2835_FIRMWARE_TURBO_ON) ? "ON":"OFF"); 1105 1106 device_printf(sc->dev, 1107 "max/min ARM %d/%dMHz, Core %d/%dMHz, SDRAM %d/%dMHz\n", 1108 HZ2MHZ(arm_max_freq), HZ2MHZ(arm_min_freq), 1109 HZ2MHZ(core_max_freq), HZ2MHZ(core_min_freq), 1110 HZ2MHZ(sdram_max_freq), HZ2MHZ(sdram_min_freq)); 1111 1112 device_printf(sc->dev, 1113 "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, " 1114 "SDRAM_P %dmV\n", 1115 OFFSET2MVOLT(voltage_core), OFFSET2MVOLT(voltage_sdram_c), 1116 OFFSET2MVOLT(voltage_sdram_i), 1117 OFFSET2MVOLT(voltage_sdram_p)); 1118 1119 device_printf(sc->dev, 1120 "max/min Core %d/%dmV, SDRAM_C %d/%dmV, SDRAM_I %d/%dmV, " 1121 "SDRAM_P %d/%dmV\n", 1122 OFFSET2MVOLT(max_voltage_core), 1123 OFFSET2MVOLT(min_voltage_core), 1124 OFFSET2MVOLT(max_voltage_sdram_c), 1125 OFFSET2MVOLT(min_voltage_sdram_c), 1126 OFFSET2MVOLT(max_voltage_sdram_i), 1127 OFFSET2MVOLT(min_voltage_sdram_i), 1128 OFFSET2MVOLT(max_voltage_sdram_p), 1129 OFFSET2MVOLT(min_voltage_sdram_p)); 1130 1131 device_printf(sc->dev, 1132 "Temperature %d.%dC\n", (temperature / 1000), 1133 (temperature % 1000) / 100); 1134 } else { /* !cpufreq_verbose && !bootverbose */ 1135 device_printf(sc->dev, 1136 "ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n", 1137 HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq), 1138 (sc->turbo_mode == BCM2835_FIRMWARE_TURBO_ON) ? "ON":"OFF"); 1139 } 1140 1141 /* keep in softc (MHz/mV) */ 1142 sc->arm_max_freq = HZ2MHZ(arm_max_freq); 1143 sc->arm_min_freq = HZ2MHZ(arm_min_freq); 1144 sc->core_max_freq = HZ2MHZ(core_max_freq); 1145 sc->core_min_freq = HZ2MHZ(core_min_freq); 1146 sc->sdram_max_freq = HZ2MHZ(sdram_max_freq); 1147 sc->sdram_min_freq = HZ2MHZ(sdram_min_freq); 1148 sc->max_voltage_core = OFFSET2MVOLT(max_voltage_core); 1149 sc->min_voltage_core = OFFSET2MVOLT(min_voltage_core); 1150 1151 /* if turbo is on, set to max values */ 1152 if (sc->turbo_mode == BCM2835_FIRMWARE_TURBO_ON) { 1153 bcm2835_cpufreq_set_clock_rate(sc, 1154 BCM2835_FIRMWARE_CLOCK_ID_ARM, arm_max_freq); 1155 DELAY(TRANSITION_LATENCY); 1156 bcm2835_cpufreq_set_clock_rate(sc, 1157 BCM2835_FIRMWARE_CLOCK_ID_CORE, core_max_freq); 1158 DELAY(TRANSITION_LATENCY); 1159 bcm2835_cpufreq_set_clock_rate(sc, 1160 BCM2835_FIRMWARE_CLOCK_ID_SDRAM, sdram_max_freq); 1161 DELAY(TRANSITION_LATENCY); 1162 } else { 1163 bcm2835_cpufreq_set_clock_rate(sc, 1164 BCM2835_FIRMWARE_CLOCK_ID_ARM, arm_min_freq); 1165 DELAY(TRANSITION_LATENCY); 1166 bcm2835_cpufreq_set_clock_rate(sc, 1167 BCM2835_FIRMWARE_CLOCK_ID_CORE, core_min_freq); 1168 DELAY(TRANSITION_LATENCY); 1169 bcm2835_cpufreq_set_clock_rate(sc, 1170 BCM2835_FIRMWARE_CLOCK_ID_SDRAM, sdram_min_freq); 1171 DELAY(TRANSITION_LATENCY); 1172 } 1173 1174 VC_UNLOCK(sc); 1175 1176 /* add human readable temperature to dev.cpu node */ 1177 cpu = device_get_parent(sc->dev); 1178 if (cpu != NULL) { 1179 ctx = device_get_sysctl_ctx(cpu); 1180 SYSCTL_ADD_PROC(ctx, 1181 SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)), OID_AUTO, 1182 "temperature", 1183 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0, 1184 sysctl_bcm2835_devcpu_temperature, "IK", 1185 "Current SoC temperature"); 1186 } 1187 1188 /* release this hook (continue boot) */ 1189 config_intrhook_disestablish(&sc->init_hook); 1190 } 1191 1192 static void 1193 bcm2835_cpufreq_identify(driver_t *driver, device_t parent) 1194 { 1195 const struct ofw_compat_data *compat; 1196 phandle_t root; 1197 1198 root = OF_finddevice("/"); 1199 for (compat = compat_data; compat->ocd_str != NULL; compat++) 1200 if (ofw_bus_node_is_compatible(root, compat->ocd_str)) 1201 break; 1202 1203 if (compat->ocd_data == 0) 1204 return; 1205 1206 DPRINTF("driver=%p, parent=%p\n", driver, parent); 1207 if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL) 1208 return; 1209 if (BUS_ADD_CHILD(parent, 0, "bcm2835_cpufreq", -1) == NULL) 1210 device_printf(parent, "add child failed\n"); 1211 } 1212 1213 static int 1214 bcm2835_cpufreq_probe(device_t dev) 1215 { 1216 1217 if (device_get_unit(dev) != 0) 1218 return (ENXIO); 1219 device_set_desc(dev, "CPU Frequency Control"); 1220 1221 return (0); 1222 } 1223 1224 static int 1225 bcm2835_cpufreq_attach(device_t dev) 1226 { 1227 struct bcm2835_cpufreq_softc *sc; 1228 struct sysctl_oid *oid; 1229 1230 /* set self dev */ 1231 sc = device_get_softc(dev); 1232 sc->dev = dev; 1233 sc->firmware = devclass_get_device( 1234 devclass_find("bcm2835_firmware"), 0); 1235 if (sc->firmware == NULL) { 1236 device_printf(dev, "Unable to find firmware device\n"); 1237 return (ENXIO); 1238 } 1239 1240 /* initial values */ 1241 sc->arm_max_freq = -1; 1242 sc->arm_min_freq = -1; 1243 sc->core_max_freq = -1; 1244 sc->core_min_freq = -1; 1245 sc->sdram_max_freq = -1; 1246 sc->sdram_min_freq = -1; 1247 sc->max_voltage_core = 0; 1248 sc->min_voltage_core = 0; 1249 1250 /* setup sysctl at first device */ 1251 if (device_get_unit(dev) == 0) { 1252 sysctl_ctx_init(&bcm2835_sysctl_ctx); 1253 /* create node for hw.cpufreq */ 1254 oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx, 1255 SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq", 1256 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, ""); 1257 1258 /* Frequency (Hz) */ 1259 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1260 OID_AUTO, "arm_freq", 1261 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0, 1262 sysctl_bcm2835_cpufreq_arm_freq, "IU", 1263 "ARM frequency (Hz)"); 1264 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1265 OID_AUTO, "core_freq", 1266 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0, 1267 sysctl_bcm2835_cpufreq_core_freq, "IU", 1268 "Core frequency (Hz)"); 1269 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1270 OID_AUTO, "sdram_freq", 1271 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0, 1272 sysctl_bcm2835_cpufreq_sdram_freq, "IU", 1273 "SDRAM frequency (Hz)"); 1274 1275 /* Turbo state */ 1276 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1277 OID_AUTO, "turbo", 1278 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0, 1279 sysctl_bcm2835_cpufreq_turbo, "IU", 1280 "Disables dynamic clocking"); 1281 1282 /* Voltage (offset from 1.2V in units of 0.025V) */ 1283 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1284 OID_AUTO, "voltage_core", 1285 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0, 1286 sysctl_bcm2835_cpufreq_voltage_core, "I", 1287 "ARM/GPU core voltage" 1288 "(offset from 1.2V in units of 0.025V)"); 1289 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1290 OID_AUTO, "voltage_sdram", 1291 CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT, sc, 1292 0, sysctl_bcm2835_cpufreq_voltage_sdram, "I", 1293 "SDRAM voltage (offset from 1.2V in units of 0.025V)"); 1294 1295 /* Voltage individual SDRAM */ 1296 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1297 OID_AUTO, "voltage_sdram_c", 1298 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 1299 0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I", 1300 "SDRAM controller voltage" 1301 "(offset from 1.2V in units of 0.025V)"); 1302 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1303 OID_AUTO, "voltage_sdram_i", 1304 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 1305 0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I", 1306 "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)"); 1307 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1308 OID_AUTO, "voltage_sdram_p", 1309 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 1310 0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I", 1311 "SDRAM phy voltage (offset from 1.2V in units of 0.025V)"); 1312 1313 /* Temperature */ 1314 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), 1315 OID_AUTO, "temperature", 1316 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0, 1317 sysctl_bcm2835_cpufreq_temperature, "I", 1318 "SoC temperature (thousandths of a degree C)"); 1319 } 1320 1321 /* ARM->VC lock */ 1322 sema_init(&vc_sema, 1, "vcsema"); 1323 1324 /* register callback for using mbox when interrupts are enabled */ 1325 sc->init_hook.ich_func = bcm2835_cpufreq_init; 1326 sc->init_hook.ich_arg = sc; 1327 1328 if (config_intrhook_establish(&sc->init_hook) != 0) { 1329 device_printf(dev, "config_intrhook_establish failed\n"); 1330 return (ENOMEM); 1331 } 1332 1333 /* this device is controlled by cpufreq(4) */ 1334 cpufreq_register(dev); 1335 1336 return (0); 1337 } 1338 1339 static int 1340 bcm2835_cpufreq_detach(device_t dev) 1341 { 1342 1343 sema_destroy(&vc_sema); 1344 1345 return (cpufreq_unregister(dev)); 1346 } 1347 1348 static int 1349 bcm2835_cpufreq_set(device_t dev, const struct cf_setting *cf) 1350 { 1351 struct bcm2835_cpufreq_softc *sc; 1352 uint32_t rate_hz, rem; 1353 int resp_freq, arm_freq, min_freq, core_freq; 1354 #ifdef DEBUG 1355 int cur_freq; 1356 #endif 1357 1358 if (cf == NULL || cf->freq < 0) 1359 return (EINVAL); 1360 1361 sc = device_get_softc(dev); 1362 1363 /* setting clock (Hz) */ 1364 rate_hz = (uint32_t)MHZ2HZ(cf->freq); 1365 rem = rate_hz % HZSTEP; 1366 rate_hz -= rem; 1367 if (rate_hz == 0) 1368 return (EINVAL); 1369 1370 /* adjust min freq */ 1371 min_freq = sc->arm_min_freq; 1372 if (sc->turbo_mode != BCM2835_FIRMWARE_TURBO_ON) 1373 if (min_freq > cpufreq_lowest_freq) 1374 min_freq = cpufreq_lowest_freq; 1375 1376 if (rate_hz < MHZ2HZ(min_freq) || rate_hz > MHZ2HZ(sc->arm_max_freq)) 1377 return (EINVAL); 1378 1379 /* set new value and verify it */ 1380 VC_LOCK(sc); 1381 #ifdef DEBUG 1382 cur_freq = bcm2835_cpufreq_get_clock_rate(sc, 1383 BCM2835_FIRMWARE_CLOCK_ID_ARM); 1384 #endif 1385 resp_freq = bcm2835_cpufreq_set_clock_rate(sc, 1386 BCM2835_FIRMWARE_CLOCK_ID_ARM, rate_hz); 1387 DELAY(TRANSITION_LATENCY); 1388 arm_freq = bcm2835_cpufreq_get_clock_rate(sc, 1389 BCM2835_FIRMWARE_CLOCK_ID_ARM); 1390 1391 /* 1392 * if non-turbo and lower than or equal min_freq, 1393 * clock down core and sdram to default first. 1394 */ 1395 if (sc->turbo_mode != BCM2835_FIRMWARE_TURBO_ON) { 1396 core_freq = bcm2835_cpufreq_get_clock_rate(sc, 1397 BCM2835_FIRMWARE_CLOCK_ID_CORE); 1398 if (rate_hz > MHZ2HZ(sc->arm_min_freq)) { 1399 bcm2835_cpufreq_set_clock_rate(sc, 1400 BCM2835_FIRMWARE_CLOCK_ID_CORE, 1401 MHZ2HZ(sc->core_max_freq)); 1402 DELAY(TRANSITION_LATENCY); 1403 bcm2835_cpufreq_set_clock_rate(sc, 1404 BCM2835_FIRMWARE_CLOCK_ID_SDRAM, 1405 MHZ2HZ(sc->sdram_max_freq)); 1406 DELAY(TRANSITION_LATENCY); 1407 } else { 1408 if (sc->core_min_freq < DEFAULT_CORE_FREQUENCY && 1409 core_freq > DEFAULT_CORE_FREQUENCY) { 1410 /* first, down to 250, then down to min */ 1411 DELAY(TRANSITION_LATENCY); 1412 bcm2835_cpufreq_set_clock_rate(sc, 1413 BCM2835_FIRMWARE_CLOCK_ID_CORE, 1414 MHZ2HZ(DEFAULT_CORE_FREQUENCY)); 1415 DELAY(TRANSITION_LATENCY); 1416 /* reset core voltage */ 1417 bcm2835_cpufreq_set_voltage(sc, 1418 BCM2835_FIRMWARE_VOLTAGE_ID_CORE, 0); 1419 DELAY(TRANSITION_LATENCY); 1420 } 1421 bcm2835_cpufreq_set_clock_rate(sc, 1422 BCM2835_FIRMWARE_CLOCK_ID_CORE, 1423 MHZ2HZ(sc->core_min_freq)); 1424 DELAY(TRANSITION_LATENCY); 1425 bcm2835_cpufreq_set_clock_rate(sc, 1426 BCM2835_FIRMWARE_CLOCK_ID_SDRAM, 1427 MHZ2HZ(sc->sdram_min_freq)); 1428 DELAY(TRANSITION_LATENCY); 1429 } 1430 } 1431 1432 VC_UNLOCK(sc); 1433 1434 if (resp_freq < 0 || arm_freq < 0 || resp_freq != arm_freq) { 1435 device_printf(dev, "wrong freq\n"); 1436 return (EIO); 1437 } 1438 DPRINTF("cpufreq: %d -> %d\n", cur_freq, arm_freq); 1439 1440 return (0); 1441 } 1442 1443 static int 1444 bcm2835_cpufreq_get(device_t dev, struct cf_setting *cf) 1445 { 1446 struct bcm2835_cpufreq_softc *sc; 1447 int arm_freq; 1448 1449 if (cf == NULL) 1450 return (EINVAL); 1451 1452 sc = device_get_softc(dev); 1453 memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf)); 1454 cf->dev = NULL; 1455 1456 /* get cuurent value */ 1457 VC_LOCK(sc); 1458 arm_freq = bcm2835_cpufreq_get_clock_rate(sc, 1459 BCM2835_FIRMWARE_CLOCK_ID_ARM); 1460 VC_UNLOCK(sc); 1461 if (arm_freq < 0) { 1462 device_printf(dev, "can't get clock\n"); 1463 return (EINVAL); 1464 } 1465 1466 /* CPU clock in MHz or 100ths of a percent. */ 1467 cf->freq = HZ2MHZ(arm_freq); 1468 /* Voltage in mV. */ 1469 cf->volts = CPUFREQ_VAL_UNKNOWN; 1470 /* Power consumed in mW. */ 1471 cf->power = CPUFREQ_VAL_UNKNOWN; 1472 /* Transition latency in us. */ 1473 cf->lat = TRANSITION_LATENCY; 1474 /* Driver providing this setting. */ 1475 cf->dev = dev; 1476 1477 return (0); 1478 } 1479 1480 static int 1481 bcm2835_cpufreq_make_freq_list(device_t dev, struct cf_setting *sets, 1482 int *count) 1483 { 1484 struct bcm2835_cpufreq_softc *sc; 1485 int freq, min_freq, volts, rem; 1486 int idx; 1487 1488 sc = device_get_softc(dev); 1489 freq = sc->arm_max_freq; 1490 min_freq = sc->arm_min_freq; 1491 1492 /* adjust head freq to STEP */ 1493 rem = freq % MHZSTEP; 1494 freq -= rem; 1495 if (freq < min_freq) 1496 freq = min_freq; 1497 1498 /* if non-turbo, add extra low freq */ 1499 if (sc->turbo_mode != BCM2835_FIRMWARE_TURBO_ON) 1500 if (min_freq > cpufreq_lowest_freq) 1501 min_freq = cpufreq_lowest_freq; 1502 1503 /* XXX RPi2 have only 900/600MHz */ 1504 idx = 0; 1505 volts = sc->min_voltage_core; 1506 sets[idx].freq = freq; 1507 sets[idx].volts = volts; 1508 sets[idx].lat = TRANSITION_LATENCY; 1509 sets[idx].dev = dev; 1510 idx++; 1511 if (freq != min_freq) { 1512 sets[idx].freq = min_freq; 1513 sets[idx].volts = volts; 1514 sets[idx].lat = TRANSITION_LATENCY; 1515 sets[idx].dev = dev; 1516 idx++; 1517 } 1518 *count = idx; 1519 1520 return (0); 1521 } 1522 1523 static int 1524 bcm2835_cpufreq_settings(device_t dev, struct cf_setting *sets, int *count) 1525 { 1526 struct bcm2835_cpufreq_softc *sc; 1527 1528 if (sets == NULL || count == NULL) 1529 return (EINVAL); 1530 1531 sc = device_get_softc(dev); 1532 if (sc->arm_min_freq < 0 || sc->arm_max_freq < 0) { 1533 printf("device is not configured\n"); 1534 return (EINVAL); 1535 } 1536 1537 /* fill data with unknown value */ 1538 memset(sets, CPUFREQ_VAL_UNKNOWN, sizeof(*sets) * (*count)); 1539 /* create new array up to count */ 1540 bcm2835_cpufreq_make_freq_list(dev, sets, count); 1541 1542 return (0); 1543 } 1544 1545 static int 1546 bcm2835_cpufreq_type(device_t dev, int *type) 1547 { 1548 1549 if (type == NULL) 1550 return (EINVAL); 1551 *type = CPUFREQ_TYPE_ABSOLUTE; 1552 1553 return (0); 1554 } 1555 1556 static device_method_t bcm2835_cpufreq_methods[] = { 1557 /* Device interface */ 1558 DEVMETHOD(device_identify, bcm2835_cpufreq_identify), 1559 DEVMETHOD(device_probe, bcm2835_cpufreq_probe), 1560 DEVMETHOD(device_attach, bcm2835_cpufreq_attach), 1561 DEVMETHOD(device_detach, bcm2835_cpufreq_detach), 1562 1563 /* cpufreq interface */ 1564 DEVMETHOD(cpufreq_drv_set, bcm2835_cpufreq_set), 1565 DEVMETHOD(cpufreq_drv_get, bcm2835_cpufreq_get), 1566 DEVMETHOD(cpufreq_drv_settings, bcm2835_cpufreq_settings), 1567 DEVMETHOD(cpufreq_drv_type, bcm2835_cpufreq_type), 1568 1569 DEVMETHOD_END 1570 }; 1571 1572 static driver_t bcm2835_cpufreq_driver = { 1573 "bcm2835_cpufreq", 1574 bcm2835_cpufreq_methods, 1575 sizeof(struct bcm2835_cpufreq_softc), 1576 }; 1577 1578 DRIVER_MODULE(bcm2835_cpufreq, cpu, bcm2835_cpufreq_driver, 0, 0); 1579 MODULE_DEPEND(bcm2835_cpufreq, bcm2835_firmware, 1, 1, 1); 1580