2 * Copyright (C) 2013-2015 Daisuke Aoyama <aoyama@peach.ne.jp>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
32 #include <sys/systm.h>
35 #include <sys/kernel.h>
37 #include <sys/malloc.h>
38 #include <sys/module.h>
39 #include <sys/mutex.h>
41 #include <sys/sysctl.h>
43 #include <machine/bus.h>
44 #include <machine/cpu.h>
45 #include <machine/intr.h>
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>
51 #include "cpufreq_if.h"
55 #define DPRINTF(fmt, ...) do { \
56 printf("%s:%u: ", __func__, __LINE__); \
57 printf(fmt, ##__VA_ARGS__); \
60 #define DPRINTF(fmt, ...)
63 #define HZ2MHZ(freq) ((freq) / (1000 * 1000))
64 #define MHZ2HZ(freq) ((freq) * (1000 * 1000))
67 #define OFFSET2MVOLT(val) (((val) / 1000))
68 #define MVOLT2OFFSET(val) (((val) * 1000))
69 #define DEFAULT_ARM_FREQUENCY 600
70 #define DEFAULT_LOWEST_FREQ 600
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
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
84 #define HZSTEP (MHZ2HZ(MHZSTEP))
87 #define VC_LOCK(sc) do { \
88 sema_wait(&vc_sema); \
90 #define VC_UNLOCK(sc) do { \
91 sema_post(&vc_sema); \
94 /* ARM->VC mailbox property semaphore */
95 static struct sema vc_sema;
97 static struct sysctl_ctx_list bcm2835_sysctl_ctx;
99 struct bcm2835_cpufreq_softc {
107 int max_voltage_core;
108 int min_voltage_core;
110 /* the values written in mbox */
118 /* mbox buffer (physical address) */
119 bus_dma_tag_t dma_tag;
120 bus_dmamap_t dma_map;
125 /* initial hook for waiting mbox intr */
126 struct intr_config_hook init_hook;
129 static int cpufreq_verbose = 0;
130 TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose);
131 static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ;
132 TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq);
136 bcm2835_dump(const void *data, int len)
138 const uint8_t *p = (const uint8_t*)data;
141 printf("dump @ %p:\n", data);
142 for (i = 0; i < len; i++) {
143 printf("%2.2x ", p[i]);
154 bcm2835_mbox_call_prop(struct bcm2835_cpufreq_softc *sc)
156 struct bcm2835_mbox_hdr *msg = (struct bcm2835_mbox_hdr *)sc->dma_buf;
157 struct bcm2835_mbox_tag_hdr *tag, *last;
165 * For multiple calls, locking is not here. The caller must have
169 /* get mbox device */
170 mbox = devclass_get_device(devclass_find("mbox"), 0);
172 device_printf(sc->dev, "can't find mbox\n");
176 /* go mailbox property */
178 bcm2835_dump(msg, 64);
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);
186 bcm2835_dump(msg, 64);
189 /* check response code */
190 if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) {
191 device_printf(sc->dev, "mbox response error\n");
195 /* tag = first tag */
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);
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);
209 /* clear response bit */
210 tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
214 tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size +
217 /* check buffer size of header */
219 device_printf(sc->dev, "mbox buffer size error\n");
228 bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc,
231 struct msg_get_clock_rate *msg;
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);
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;
267 /* call mailbox property */
268 err = bcm2835_mbox_call_prop(sc);
270 device_printf(sc->dev, "can't get clock rate (id=%u)\n",
276 rate = (int)msg->body.resp.rate_hz;
277 DPRINTF("clock = %d(Hz)\n", rate);
282 bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc,
285 struct msg_get_max_clock_rate *msg;
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);
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;
321 /* call mailbox property */
322 err = bcm2835_mbox_call_prop(sc);
324 device_printf(sc->dev, "can't get max clock rate (id=%u)\n",
330 rate = (int)msg->body.resp.rate_hz;
331 DPRINTF("clock = %d(Hz)\n", rate);
336 bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc,
339 struct msg_get_min_clock_rate *msg;
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);
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;
375 /* call mailbox property */
376 err = bcm2835_mbox_call_prop(sc);
378 device_printf(sc->dev, "can't get min clock rate (id=%u)\n",
384 rate = (int)msg->body.resp.rate_hz;
385 DPRINTF("clock = %d(Hz)\n", rate);
390 bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
391 uint32_t clock_id, uint32_t rate_hz)
393 struct msg_set_clock_rate *msg;
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);
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;
431 /* call mailbox property */
432 err = bcm2835_mbox_call_prop(sc);
434 device_printf(sc->dev, "can't set clock rate (id=%u)\n",
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);
445 * XXX: the core clock is unable to change at once,
446 * to change certainly, write it twice now.
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;
460 /* call mailbox property */
461 err = bcm2835_mbox_call_prop(sc);
463 device_printf(sc->dev,
464 "can't set clock rate (id=%u)\n", clock_id);
470 rate = (int)msg->body.resp.rate_hz;
471 DPRINTF("clock = %d(Hz)\n", rate);
476 bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc)
478 struct msg_get_turbo *msg;
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);
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;
514 /* call mailbox property */
515 err = bcm2835_mbox_call_prop(sc);
517 device_printf(sc->dev, "can't get turbo\n");
521 /* result 0=non-turbo, 1=turbo */
522 level = (int)msg->body.resp.level;
523 DPRINTF("level = %d\n", level);
528 bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level)
530 struct msg_set_turbo *msg;
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);
557 /* replace unknown value to OFF */
558 if (level != BCM2835_MBOX_TURBO_ON && level != BCM2835_MBOX_TURBO_OFF)
559 level = BCM2835_MBOX_TURBO_OFF;
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;
572 /* call mailbox property */
573 err = bcm2835_mbox_call_prop(sc);
575 device_printf(sc->dev, "can't set turbo\n");
579 /* result 0=non-turbo, 1=turbo */
580 value = (int)msg->body.resp.level;
581 DPRINTF("level = %d\n", value);
586 bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc,
589 struct msg_get_voltage *msg;
604 * u32: value (offset from 1.2V in units of 0.025V)
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);
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;
625 /* call mailbox property */
626 err = bcm2835_mbox_call_prop(sc);
628 device_printf(sc->dev, "can't get voltage\n");
632 /* result (offset from 1.2V) */
633 value = (int)msg->body.resp.value;
634 DPRINTF("value = %d\n", value);
639 bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc,
642 struct msg_get_max_voltage *msg;
657 * u32: value (offset from 1.2V in units of 0.025V)
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);
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;
678 /* call mailbox property */
679 err = bcm2835_mbox_call_prop(sc);
681 device_printf(sc->dev, "can't get max voltage\n");
685 /* result (offset from 1.2V) */
686 value = (int)msg->body.resp.value;
687 DPRINTF("value = %d\n", value);
691 bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc,
694 struct msg_get_min_voltage *msg;
709 * u32: value (offset from 1.2V in units of 0.025V)
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);
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;
730 /* call mailbox property */
731 err = bcm2835_mbox_call_prop(sc);
733 device_printf(sc->dev, "can't get min voltage\n");
737 /* result (offset from 1.2V) */
738 value = (int)msg->body.resp.value;
739 DPRINTF("value = %d\n", value);
744 bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc,
745 uint32_t voltage_id, int32_t value)
747 struct msg_set_voltage *msg;
757 * u32: value (offset from 1.2V in units of 0.025V)
762 * u32: value (offset from 1.2V in units of 0.025V)
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).
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);
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);
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;
795 /* call mailbox property */
796 err = bcm2835_mbox_call_prop(sc);
798 device_printf(sc->dev, "can't set voltage\n");
802 /* result (offset from 1.2V) */
803 value = (int)msg->body.resp.value;
804 DPRINTF("value = %d\n", value);
809 bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc)
811 struct msg_get_temperature *msg;
821 * u32: temperature id
825 * u32: temperature id
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);
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;
847 /* call mailbox property */
848 err = bcm2835_mbox_call_prop(sc);
850 device_printf(sc->dev, "can't get temperature\n");
854 /* result (temperature of degree C) */
855 value = (int)msg->body.resp.value;
856 DPRINTF("value = %d\n", value);
863 sysctl_bcm2835_cpufreq_arm_freq(SYSCTL_HANDLER_ARGS)
865 struct bcm2835_cpufreq_softc *sc = arg1;
869 /* get realtime value */
871 val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM);
873 if (val == MSG_ERROR)
876 err = sysctl_handle_int(oidp, &val, 0, req);
877 if (err || !req->newptr) /* error || read request */
882 err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
885 if (err == MSG_ERROR) {
886 device_printf(sc->dev, "set clock arm_freq error\n");
889 DELAY(TRANSITION_LATENCY);
895 sysctl_bcm2835_cpufreq_core_freq(SYSCTL_HANDLER_ARGS)
897 struct bcm2835_cpufreq_softc *sc = arg1;
901 /* get realtime value */
903 val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE);
905 if (val == MSG_ERROR)
908 err = sysctl_handle_int(oidp, &val, 0, req);
909 if (err || !req->newptr) /* error || read request */
914 err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
916 if (err == MSG_ERROR) {
918 device_printf(sc->dev, "set clock core_freq error\n");
922 DELAY(TRANSITION_LATENCY);
928 sysctl_bcm2835_cpufreq_sdram_freq(SYSCTL_HANDLER_ARGS)
930 struct bcm2835_cpufreq_softc *sc = arg1;
934 /* get realtime value */
936 val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM);
938 if (val == MSG_ERROR)
941 err = sysctl_handle_int(oidp, &val, 0, req);
942 if (err || !req->newptr) /* error || read request */
947 err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM,
950 if (err == MSG_ERROR) {
951 device_printf(sc->dev, "set clock sdram_freq error\n");
954 DELAY(TRANSITION_LATENCY);
960 sysctl_bcm2835_cpufreq_turbo(SYSCTL_HANDLER_ARGS)
962 struct bcm2835_cpufreq_softc *sc = arg1;
966 /* get realtime value */
968 val = bcm2835_cpufreq_get_turbo(sc);
970 if (val == MSG_ERROR)
973 err = sysctl_handle_int(oidp, &val, 0, req);
974 if (err || !req->newptr) /* error || read request */
979 sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
981 sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;
984 err = bcm2835_cpufreq_set_turbo(sc, sc->turbo_mode);
986 if (err == MSG_ERROR) {
987 device_printf(sc->dev, "set turbo error\n");
990 DELAY(TRANSITION_LATENCY);
996 sysctl_bcm2835_cpufreq_voltage_core(SYSCTL_HANDLER_ARGS)
998 struct bcm2835_cpufreq_softc *sc = arg1;
1002 /* get realtime value */
1004 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE);
1006 if (val == MSG_ERROR)
1009 err = sysctl_handle_int(oidp, &val, 0, req);
1010 if (err || !req->newptr) /* error || read request */
1014 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1016 sc->voltage_core = val;
1019 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE,
1022 if (err == MSG_ERROR) {
1023 device_printf(sc->dev, "set voltage core error\n");
1026 DELAY(TRANSITION_LATENCY);
1032 sysctl_bcm2835_cpufreq_voltage_sdram_c(SYSCTL_HANDLER_ARGS)
1034 struct bcm2835_cpufreq_softc *sc = arg1;
1038 /* get realtime value */
1040 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
1042 if (val == MSG_ERROR)
1045 err = sysctl_handle_int(oidp, &val, 0, req);
1046 if (err || !req->newptr) /* error || read request */
1050 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1052 sc->voltage_sdram_c = val;
1055 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C,
1056 sc->voltage_sdram_c);
1058 if (err == MSG_ERROR) {
1059 device_printf(sc->dev, "set voltage sdram_c error\n");
1062 DELAY(TRANSITION_LATENCY);
1068 sysctl_bcm2835_cpufreq_voltage_sdram_i(SYSCTL_HANDLER_ARGS)
1070 struct bcm2835_cpufreq_softc *sc = arg1;
1074 /* get realtime value */
1076 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
1078 if (val == MSG_ERROR)
1081 err = sysctl_handle_int(oidp, &val, 0, req);
1082 if (err || !req->newptr) /* error || read request */
1086 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1088 sc->voltage_sdram_i = val;
1091 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I,
1092 sc->voltage_sdram_i);
1094 if (err == MSG_ERROR) {
1095 device_printf(sc->dev, "set voltage sdram_i error\n");
1098 DELAY(TRANSITION_LATENCY);
1104 sysctl_bcm2835_cpufreq_voltage_sdram_p(SYSCTL_HANDLER_ARGS)
1106 struct bcm2835_cpufreq_softc *sc = arg1;
1110 /* get realtime value */
1112 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
1114 if (val == MSG_ERROR)
1117 err = sysctl_handle_int(oidp, &val, 0, req);
1118 if (err || !req->newptr) /* error || read request */
1122 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1124 sc->voltage_sdram_p = val;
1127 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P,
1128 sc->voltage_sdram_p);
1130 if (err == MSG_ERROR) {
1131 device_printf(sc->dev, "set voltage sdram_p error\n");
1134 DELAY(TRANSITION_LATENCY);
1140 sysctl_bcm2835_cpufreq_voltage_sdram(SYSCTL_HANDLER_ARGS)
1142 struct bcm2835_cpufreq_softc *sc = arg1;
1146 /* multiple write only */
1150 err = sysctl_handle_int(oidp, &val, 0, req);
1155 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1157 sc->voltage_sdram = val;
1160 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C,
1162 if (err == MSG_ERROR) {
1164 device_printf(sc->dev, "set voltage sdram_c error\n");
1167 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I,
1169 if (err == MSG_ERROR) {
1171 device_printf(sc->dev, "set voltage sdram_i error\n");
1174 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P,
1176 if (err == MSG_ERROR) {
1178 device_printf(sc->dev, "set voltage sdram_p error\n");
1182 DELAY(TRANSITION_LATENCY);
1188 sysctl_bcm2835_cpufreq_temperature(SYSCTL_HANDLER_ARGS)
1190 struct bcm2835_cpufreq_softc *sc = arg1;
1194 /* get realtime value */
1196 val = bcm2835_cpufreq_get_temperature(sc);
1198 if (val == MSG_ERROR)
1201 err = sysctl_handle_int(oidp, &val, 0, req);
1202 if (err || !req->newptr) /* error || read request */
1210 sysctl_bcm2835_devcpu_temperature(SYSCTL_HANDLER_ARGS)
1212 struct bcm2835_cpufreq_softc *sc = arg1;
1216 /* get realtime value */
1218 val = bcm2835_cpufreq_get_temperature(sc);
1220 if (val == MSG_ERROR)
1223 /* 1/1000 celsius (raw) to 1/10 kelvin */
1224 val = val / 100 + TZ_ZEROC;
1226 err = sysctl_handle_int(oidp, &val, 0, req);
1227 if (err || !req->newptr) /* error || read request */
1236 bcm2835_cpufreq_init(void *arg)
1238 struct bcm2835_cpufreq_softc *sc = arg;
1239 struct sysctl_ctx_list *ctx;
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;
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);
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);
1276 turbo = bcm2835_cpufreq_get_turbo(sc);
1278 sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
1280 sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;
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);
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;
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);
1318 temperature = bcm2835_cpufreq_get_temperature(sc);
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");
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));
1334 device_printf(sc->dev,
1335 "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, "
1337 OFFSET2MVOLT(voltage_core), OFFSET2MVOLT(voltage_sdram_c),
1338 OFFSET2MVOLT(voltage_sdram_i),
1339 OFFSET2MVOLT(voltage_sdram_p));
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));
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");
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);
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,
1377 DELAY(TRANSITION_LATENCY);
1378 bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
1380 DELAY(TRANSITION_LATENCY);
1381 bcm2835_cpufreq_set_clock_rate(sc,
1382 BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_max_freq);
1383 DELAY(TRANSITION_LATENCY);
1385 bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
1387 DELAY(TRANSITION_LATENCY);
1388 bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
1390 DELAY(TRANSITION_LATENCY);
1391 bcm2835_cpufreq_set_clock_rate(sc,
1392 BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_min_freq);
1393 DELAY(TRANSITION_LATENCY);
1398 /* add human readable temperature to dev.cpu node */
1399 cpu = device_get_parent(sc->dev);
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");
1409 /* release this hook (continue boot) */
1410 config_intrhook_disestablish(&sc->init_hook);
1414 bcm2835_cpufreq_identify(driver_t *driver, device_t parent)
1417 DPRINTF("driver=%p, parent=%p\n", driver, parent);
1418 if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL)
1420 if (BUS_ADD_CHILD(parent, 0, "bcm2835_cpufreq", -1) == NULL)
1421 device_printf(parent, "add child failed\n");
1425 bcm2835_cpufreq_probe(device_t dev)
1428 if (device_get_unit(dev) != 0)
1430 device_set_desc(dev, "CPU Frequency Control");
1436 bcm2835_cpufreq_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
1442 addr = (bus_addr_t *)arg;
1443 *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
1447 bcm2835_cpufreq_attach(device_t dev)
1449 struct bcm2835_cpufreq_softc *sc;
1450 struct sysctl_oid *oid;
1454 sc = device_get_softc(dev);
1457 /* initial values */
1458 sc->arm_max_freq = -1;
1459 sc->arm_min_freq = -1;
1460 sc->core_max_freq = -1;
1461 sc->core_min_freq = -1;
1462 sc->sdram_max_freq = -1;
1463 sc->sdram_min_freq = -1;
1464 sc->max_voltage_core = 0;
1465 sc->min_voltage_core = 0;
1467 /* create VC mbox buffer */
1468 sc->dma_size = PAGE_SIZE;
1469 err = bus_dma_tag_create(
1470 bus_get_dma_tag(sc->dev),
1471 PAGE_SIZE, 0, /* alignment, boundary */
1472 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
1473 BUS_SPACE_MAXADDR, /* highaddr */
1474 NULL, NULL, /* filter, filterarg */
1475 sc->dma_size, 1, /* maxsize, nsegments */
1476 sc->dma_size, 0, /* maxsegsize, flags */
1477 NULL, NULL, /* lockfunc, lockarg */
1480 device_printf(dev, "can't create DMA tag\n");
1484 err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->dma_buf, 0,
1487 bus_dma_tag_destroy(sc->dma_tag);
1488 device_printf(dev, "can't allocate dmamem\n");
1492 err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->dma_buf,
1493 sc->dma_size, bcm2835_cpufreq_cb, &sc->dma_phys, 0);
1495 bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
1496 bus_dma_tag_destroy(sc->dma_tag);
1497 device_printf(dev, "can't load DMA map\n");
1500 /* OK, ready to use VC buffer */
1502 /* setup sysctl at first device */
1503 if (device_get_unit(dev) == 0) {
1504 sysctl_ctx_init(&bcm2835_sysctl_ctx);
1505 /* create node for hw.cpufreq */
1506 oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx,
1507 SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq",
1508 CTLFLAG_RD, NULL, "");
1510 /* Frequency (Hz) */
1511 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1512 OID_AUTO, "arm_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1513 sysctl_bcm2835_cpufreq_arm_freq, "IU",
1514 "ARM frequency (Hz)");
1515 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1516 OID_AUTO, "core_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1517 sysctl_bcm2835_cpufreq_core_freq, "IU",
1518 "Core frequency (Hz)");
1519 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1520 OID_AUTO, "sdram_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1521 sysctl_bcm2835_cpufreq_sdram_freq, "IU",
1522 "SDRAM frequency (Hz)");
1525 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1526 OID_AUTO, "turbo", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1527 sysctl_bcm2835_cpufreq_turbo, "IU",
1528 "Disables dynamic clocking");
1530 /* Voltage (offset from 1.2V in units of 0.025V) */
1531 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1532 OID_AUTO, "voltage_core", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1533 sysctl_bcm2835_cpufreq_voltage_core, "I",
1534 "ARM/GPU core voltage"
1535 "(offset from 1.2V in units of 0.025V)");
1536 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1537 OID_AUTO, "voltage_sdram", CTLTYPE_INT | CTLFLAG_WR, sc,
1538 0, sysctl_bcm2835_cpufreq_voltage_sdram, "I",
1539 "SDRAM voltage (offset from 1.2V in units of 0.025V)");
1541 /* Voltage individual SDRAM */
1542 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1543 OID_AUTO, "voltage_sdram_c", CTLTYPE_INT | CTLFLAG_RW, sc,
1544 0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I",
1545 "SDRAM controller voltage"
1546 "(offset from 1.2V in units of 0.025V)");
1547 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1548 OID_AUTO, "voltage_sdram_i", CTLTYPE_INT | CTLFLAG_RW, sc,
1549 0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I",
1550 "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)");
1551 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1552 OID_AUTO, "voltage_sdram_p", CTLTYPE_INT | CTLFLAG_RW, sc,
1553 0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I",
1554 "SDRAM phy voltage (offset from 1.2V in units of 0.025V)");
1557 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1558 OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
1559 sysctl_bcm2835_cpufreq_temperature, "I",
1560 "SoC temperature (thousandths of a degree C)");
1564 sema_init(&vc_sema, 1, "vcsema");
1566 /* register callback for using mbox when interrupts are enabled */
1567 sc->init_hook.ich_func = bcm2835_cpufreq_init;
1568 sc->init_hook.ich_arg = sc;
1570 if (config_intrhook_establish(&sc->init_hook) != 0) {
1571 bus_dmamap_unload(sc->dma_tag, sc->dma_map);
1572 bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
1573 bus_dma_tag_destroy(sc->dma_tag);
1574 device_printf(dev, "config_intrhook_establish failed\n");
1578 /* this device is controlled by cpufreq(4) */
1579 cpufreq_register(dev);
1585 bcm2835_cpufreq_detach(device_t dev)
1587 struct bcm2835_cpufreq_softc *sc;
1589 sc = device_get_softc(dev);
1591 sema_destroy(&vc_sema);
1593 if (sc->dma_phys != 0)
1594 bus_dmamap_unload(sc->dma_tag, sc->dma_map);
1595 if (sc->dma_buf != NULL)
1596 bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
1597 if (sc->dma_tag != NULL)
1598 bus_dma_tag_destroy(sc->dma_tag);
1600 return (cpufreq_unregister(dev));
1604 bcm2835_cpufreq_set(device_t dev, const struct cf_setting *cf)
1606 struct bcm2835_cpufreq_softc *sc;
1607 uint32_t rate_hz, rem;
1608 int cur_freq, resp_freq, arm_freq, min_freq, core_freq;
1610 if (cf == NULL || cf->freq < 0)
1613 sc = device_get_softc(dev);
1615 /* setting clock (Hz) */
1616 rate_hz = (uint32_t)MHZ2HZ(cf->freq);
1617 rem = rate_hz % HZSTEP;
1622 /* adjust min freq */
1623 min_freq = sc->arm_min_freq;
1624 if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON)
1625 if (min_freq > cpufreq_lowest_freq)
1626 min_freq = cpufreq_lowest_freq;
1628 if (rate_hz < MHZ2HZ(min_freq) || rate_hz > MHZ2HZ(sc->arm_max_freq))
1631 /* set new value and verify it */
1633 cur_freq = bcm2835_cpufreq_get_clock_rate(sc,
1634 BCM2835_MBOX_CLOCK_ID_ARM);
1635 resp_freq = bcm2835_cpufreq_set_clock_rate(sc,
1636 BCM2835_MBOX_CLOCK_ID_ARM, rate_hz);
1637 DELAY(TRANSITION_LATENCY);
1638 arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
1639 BCM2835_MBOX_CLOCK_ID_ARM);
1642 * if non-turbo and lower than or equal min_freq,
1643 * clock down core and sdram to default first.
1645 if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON) {
1646 core_freq = bcm2835_cpufreq_get_clock_rate(sc,
1647 BCM2835_MBOX_CLOCK_ID_CORE);
1648 if (rate_hz > MHZ2HZ(sc->arm_min_freq)) {
1649 bcm2835_cpufreq_set_clock_rate(sc,
1650 BCM2835_MBOX_CLOCK_ID_CORE,
1651 MHZ2HZ(sc->core_max_freq));
1652 DELAY(TRANSITION_LATENCY);
1653 bcm2835_cpufreq_set_clock_rate(sc,
1654 BCM2835_MBOX_CLOCK_ID_SDRAM,
1655 MHZ2HZ(sc->sdram_max_freq));
1656 DELAY(TRANSITION_LATENCY);
1658 if (sc->core_min_freq < DEFAULT_CORE_FREQUENCY &&
1659 core_freq > DEFAULT_CORE_FREQUENCY) {
1660 /* first, down to 250, then down to min */
1661 DELAY(TRANSITION_LATENCY);
1662 bcm2835_cpufreq_set_clock_rate(sc,
1663 BCM2835_MBOX_CLOCK_ID_CORE,
1664 MHZ2HZ(DEFAULT_CORE_FREQUENCY));
1665 DELAY(TRANSITION_LATENCY);
1666 /* reset core voltage */
1667 bcm2835_cpufreq_set_voltage(sc,
1668 BCM2835_MBOX_VOLTAGE_ID_CORE, 0);
1669 DELAY(TRANSITION_LATENCY);
1671 bcm2835_cpufreq_set_clock_rate(sc,
1672 BCM2835_MBOX_CLOCK_ID_CORE,
1673 MHZ2HZ(sc->core_min_freq));
1674 DELAY(TRANSITION_LATENCY);
1675 bcm2835_cpufreq_set_clock_rate(sc,
1676 BCM2835_MBOX_CLOCK_ID_SDRAM,
1677 MHZ2HZ(sc->sdram_min_freq));
1678 DELAY(TRANSITION_LATENCY);
1684 if (resp_freq < 0 || arm_freq < 0 || resp_freq != arm_freq) {
1685 device_printf(dev, "wrong freq\n");
1688 DPRINTF("cpufreq: %d -> %d\n", cur_freq, arm_freq);
1694 bcm2835_cpufreq_get(device_t dev, struct cf_setting *cf)
1696 struct bcm2835_cpufreq_softc *sc;
1702 sc = device_get_softc(dev);
1703 memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf));
1706 /* get cuurent value */
1708 arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
1709 BCM2835_MBOX_CLOCK_ID_ARM);
1712 device_printf(dev, "can't get clock\n");
1716 /* CPU clock in MHz or 100ths of a percent. */
1717 cf->freq = HZ2MHZ(arm_freq);
1718 /* Voltage in mV. */
1719 cf->volts = CPUFREQ_VAL_UNKNOWN;
1720 /* Power consumed in mW. */
1721 cf->power = CPUFREQ_VAL_UNKNOWN;
1722 /* Transition latency in us. */
1723 cf->lat = TRANSITION_LATENCY;
1724 /* Driver providing this setting. */
1731 bcm2835_cpufreq_make_freq_list(device_t dev, struct cf_setting *sets,
1734 struct bcm2835_cpufreq_softc *sc;
1735 int freq, min_freq, volts, rem;
1738 sc = device_get_softc(dev);
1739 freq = sc->arm_max_freq;
1740 min_freq = sc->arm_min_freq;
1742 /* adjust head freq to STEP */
1743 rem = freq % MHZSTEP;
1745 if (freq < min_freq)
1748 /* if non-turbo, add extra low freq */
1749 if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON)
1750 if (min_freq > cpufreq_lowest_freq)
1751 min_freq = cpufreq_lowest_freq;
1754 /* XXX RPi2 have only 900/600MHz */
1756 volts = sc->min_voltage_core;
1757 sets[idx].freq = freq;
1758 sets[idx].volts = volts;
1759 sets[idx].lat = TRANSITION_LATENCY;
1760 sets[idx].dev = dev;
1762 if (freq != min_freq) {
1763 sets[idx].freq = min_freq;
1764 sets[idx].volts = volts;
1765 sets[idx].lat = TRANSITION_LATENCY;
1766 sets[idx].dev = dev;
1770 /* from freq to min_freq */
1771 for (idx = 0; idx < *count && freq >= min_freq; idx++) {
1772 if (freq > sc->arm_min_freq)
1773 volts = sc->max_voltage_core;
1775 volts = sc->min_voltage_core;
1776 sets[idx].freq = freq;
1777 sets[idx].volts = volts;
1778 sets[idx].lat = TRANSITION_LATENCY;
1779 sets[idx].dev = dev;
1789 bcm2835_cpufreq_settings(device_t dev, struct cf_setting *sets, int *count)
1791 struct bcm2835_cpufreq_softc *sc;
1793 if (sets == NULL || count == NULL)
1796 sc = device_get_softc(dev);
1797 if (sc->arm_min_freq < 0 || sc->arm_max_freq < 0) {
1798 printf("device is not configured\n");
1802 /* fill data with unknown value */
1803 memset(sets, CPUFREQ_VAL_UNKNOWN, sizeof(*sets) * (*count));
1804 /* create new array up to count */
1805 bcm2835_cpufreq_make_freq_list(dev, sets, count);
1811 bcm2835_cpufreq_type(device_t dev, int *type)
1816 *type = CPUFREQ_TYPE_ABSOLUTE;
1821 static device_method_t bcm2835_cpufreq_methods[] = {
1822 /* Device interface */
1823 DEVMETHOD(device_identify, bcm2835_cpufreq_identify),
1824 DEVMETHOD(device_probe, bcm2835_cpufreq_probe),
1825 DEVMETHOD(device_attach, bcm2835_cpufreq_attach),
1826 DEVMETHOD(device_detach, bcm2835_cpufreq_detach),
1828 /* cpufreq interface */
1829 DEVMETHOD(cpufreq_drv_set, bcm2835_cpufreq_set),
1830 DEVMETHOD(cpufreq_drv_get, bcm2835_cpufreq_get),
1831 DEVMETHOD(cpufreq_drv_settings, bcm2835_cpufreq_settings),
1832 DEVMETHOD(cpufreq_drv_type, bcm2835_cpufreq_type),
1837 static devclass_t bcm2835_cpufreq_devclass;
1838 static driver_t bcm2835_cpufreq_driver = {
1840 bcm2835_cpufreq_methods,
1841 sizeof(struct bcm2835_cpufreq_softc),
1844 DRIVER_MODULE(bcm2835_cpufreq, cpu, bcm2835_cpufreq_driver,
1845 bcm2835_cpufreq_devclass, 0, 0);