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