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