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