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