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