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