2 * Copyright (C) 2013-2014 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))
65 #define OFFSET2MVOLT(val) (1200 + ((val) * 25))
66 #define MVOLT2OFFSET(val) (((val) - 1200) / 25)
68 #define DEFAULT_ARM_FREQUENCY 700
69 #define DEFAULT_CORE_FREQUENCY 250
70 #define DEFAULT_SDRAM_FREQUENCY 400
71 #define DEFAULT_LOWEST_FREQ 300
72 #define TRANSITION_LATENCY 1000
73 #define MIN_OVER_VOLTAGE -16
74 #define MAX_OVER_VOLTAGE 6
75 #define MSG_ERROR -999999999
77 #define HZSTEP (MHZ2HZ(MHZSTEP))
80 #define VC_LOCK(sc) do { \
81 sema_wait(&vc_sema); \
83 #define VC_UNLOCK(sc) do { \
84 sema_post(&vc_sema); \
87 /* ARM->VC mailbox property semaphore */
88 static struct sema vc_sema;
90 static struct sysctl_ctx_list bcm2835_sysctl_ctx;
92 struct bcm2835_cpufreq_softc {
100 int max_voltage_core;
101 int min_voltage_core;
103 /* the values written in mbox */
111 /* mbox buffer (physical address) */
112 bus_dma_tag_t dma_tag;
113 bus_dmamap_t dma_map;
118 /* initial hook for waiting mbox intr */
119 struct intr_config_hook init_hook;
122 static int cpufreq_verbose = 0;
123 TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose);
124 static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ;
125 TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq);
129 bcm2835_dump(const void *data, int len)
131 const uint8_t *p = (const uint8_t*)data;
134 printf("dump @ %p:\n", data);
135 for (i = 0; i < len; i++) {
136 printf("%2.2x ", p[i]);
147 bcm2835_mbox_call_prop(struct bcm2835_cpufreq_softc *sc)
149 struct bcm2835_mbox_hdr *msg = (struct bcm2835_mbox_hdr *)sc->dma_buf;
150 struct bcm2835_mbox_tag_hdr *tag, *last;
158 * For multiple calls, locking is not here. The caller must have
162 /* get mbox device */
163 mbox = devclass_get_device(devclass_find("mbox"), 0);
165 device_printf(sc->dev, "can't find mbox\n");
169 /* go mailbox property */
171 bcm2835_dump(msg, 64);
173 bus_dmamap_sync(sc->dma_tag, sc->dma_map,
174 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
175 MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)sc->dma_phys);
176 MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &err);
177 bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_POSTREAD);
179 bcm2835_dump(msg, 64);
182 /* check response code */
183 if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) {
184 device_printf(sc->dev, "mbox response error\n");
188 /* tag = first tag */
190 hdr_size = sizeof(struct bcm2835_mbox_hdr);
191 tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size);
192 /* last = end of buffer specified by header */
193 last = (struct bcm2835_mbox_tag_hdr *)(up + msg->buf_size);
195 /* loop unitl end tag (=0x0) */
196 hdr_size = sizeof(struct bcm2835_mbox_tag_hdr);
197 for (idx = 0; tag->tag != 0; idx++) {
198 if ((tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) == 0) {
199 device_printf(sc->dev, "tag%d response error\n", idx);
202 /* clear response bit */
203 tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
207 tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size +
210 /* check buffer size of header */
212 device_printf(sc->dev, "mbox buffer size error\n");
221 bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc,
224 struct msg_get_clock_rate *msg;
242 /* using DMA buffer for VC */
243 msg = (struct msg_get_clock_rate *)sc->dma_buf;
244 if (sizeof(*msg) > sc->dma_size) {
245 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
246 sizeof(*msg), sc->dma_size);
250 /* setup single tag buffer */
251 memset(msg, 0, sizeof(*msg));
252 msg->hdr.buf_size = sizeof(*msg);
253 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
254 msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
255 msg->tag_hdr.val_buf_size = sizeof(msg->body);
256 msg->tag_hdr.val_len = sizeof(msg->body.req);
257 msg->body.req.clock_id = clock_id;
260 /* call mailbox property */
261 err = bcm2835_mbox_call_prop(sc);
263 device_printf(sc->dev, "can't get clock rate (id=%u)\n",
269 rate = (int)msg->body.resp.rate_hz;
270 DPRINTF("clock = %d(Hz)\n", rate);
275 bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc,
278 struct msg_get_max_clock_rate *msg;
296 /* using DMA buffer for VC */
297 msg = (struct msg_get_max_clock_rate *)sc->dma_buf;
298 if (sizeof(*msg) > sc->dma_size) {
299 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
300 sizeof(*msg), sc->dma_size);
304 /* setup single tag buffer */
305 memset(msg, 0, sizeof(*msg));
306 msg->hdr.buf_size = sizeof(*msg);
307 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
308 msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE;
309 msg->tag_hdr.val_buf_size = sizeof(msg->body);
310 msg->tag_hdr.val_len = sizeof(msg->body.req);
311 msg->body.req.clock_id = clock_id;
314 /* call mailbox property */
315 err = bcm2835_mbox_call_prop(sc);
317 device_printf(sc->dev, "can't get max clock rate (id=%u)\n",
323 rate = (int)msg->body.resp.rate_hz;
324 DPRINTF("clock = %d(Hz)\n", rate);
329 bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc,
332 struct msg_get_min_clock_rate *msg;
350 /* using DMA buffer for VC */
351 msg = (struct msg_get_min_clock_rate *)sc->dma_buf;
352 if (sizeof(*msg) > sc->dma_size) {
353 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
354 sizeof(*msg), sc->dma_size);
358 /* setup single tag buffer */
359 memset(msg, 0, sizeof(*msg));
360 msg->hdr.buf_size = sizeof(*msg);
361 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
362 msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE;
363 msg->tag_hdr.val_buf_size = sizeof(msg->body);
364 msg->tag_hdr.val_len = sizeof(msg->body.req);
365 msg->body.req.clock_id = clock_id;
368 /* call mailbox property */
369 err = bcm2835_mbox_call_prop(sc);
371 device_printf(sc->dev, "can't get min clock rate (id=%u)\n",
377 rate = (int)msg->body.resp.rate_hz;
378 DPRINTF("clock = %d(Hz)\n", rate);
383 bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
384 uint32_t clock_id, uint32_t rate_hz)
386 struct msg_set_clock_rate *msg;
405 /* using DMA buffer for VC */
406 msg = (struct msg_set_clock_rate *)sc->dma_buf;
407 if (sizeof(*msg) > sc->dma_size) {
408 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
409 sizeof(*msg), sc->dma_size);
413 /* setup single tag buffer */
414 memset(msg, 0, sizeof(*msg));
415 msg->hdr.buf_size = sizeof(*msg);
416 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
417 msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
418 msg->tag_hdr.val_buf_size = sizeof(msg->body);
419 msg->tag_hdr.val_len = sizeof(msg->body.req);
420 msg->body.req.clock_id = clock_id;
421 msg->body.req.rate_hz = rate_hz;
424 /* call mailbox property */
425 err = bcm2835_mbox_call_prop(sc);
427 device_printf(sc->dev, "can't set clock rate (id=%u)\n",
432 /* workaround for core clock */
433 if (clock_id == BCM2835_MBOX_CLOCK_ID_CORE) {
434 /* for safety (may change voltage without changing clock) */
435 DELAY(TRANSITION_LATENCY);
438 * XXX: the core clock is unable to change at once,
439 * to change certainly, write it twice now.
442 /* setup single tag buffer */
443 memset(msg, 0, sizeof(*msg));
444 msg->hdr.buf_size = sizeof(*msg);
445 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
446 msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
447 msg->tag_hdr.val_buf_size = sizeof(msg->body);
448 msg->tag_hdr.val_len = sizeof(msg->body.req);
449 msg->body.req.clock_id = clock_id;
450 msg->body.req.rate_hz = rate_hz;
453 /* call mailbox property */
454 err = bcm2835_mbox_call_prop(sc);
456 device_printf(sc->dev,
457 "can't set clock rate (id=%u)\n", clock_id);
463 rate = (int)msg->body.resp.rate_hz;
464 DPRINTF("clock = %d(Hz)\n", rate);
469 bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc)
471 struct msg_get_turbo *msg;
489 /* using DMA buffer for VC */
490 msg = (struct msg_get_turbo *)sc->dma_buf;
491 if (sizeof(*msg) > sc->dma_size) {
492 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
493 sizeof(*msg), sc->dma_size);
497 /* setup single tag buffer */
498 memset(msg, 0, sizeof(*msg));
499 msg->hdr.buf_size = sizeof(*msg);
500 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
501 msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TURBO;
502 msg->tag_hdr.val_buf_size = sizeof(msg->body);
503 msg->tag_hdr.val_len = sizeof(msg->body.req);
504 msg->body.req.id = 0;
507 /* call mailbox property */
508 err = bcm2835_mbox_call_prop(sc);
510 device_printf(sc->dev, "can't get turbo\n");
514 /* result 0=non-turbo, 1=turbo */
515 level = (int)msg->body.resp.level;
516 DPRINTF("level = %d\n", level);
521 bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level)
523 struct msg_set_turbo *msg;
542 /* using DMA buffer for VC */
543 msg = (struct msg_set_turbo *)sc->dma_buf;
544 if (sizeof(*msg) > sc->dma_size) {
545 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
546 sizeof(*msg), sc->dma_size);
550 /* replace unknown value to OFF */
551 if (level != BCM2835_MBOX_TURBO_ON && level != BCM2835_MBOX_TURBO_OFF)
552 level = BCM2835_MBOX_TURBO_OFF;
554 /* setup single tag buffer */
555 memset(msg, 0, sizeof(*msg));
556 msg->hdr.buf_size = sizeof(*msg);
557 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
558 msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_TURBO;
559 msg->tag_hdr.val_buf_size = sizeof(msg->body);
560 msg->tag_hdr.val_len = sizeof(msg->body.req);
561 msg->body.req.id = 0;
562 msg->body.req.level = level;
565 /* call mailbox property */
566 err = bcm2835_mbox_call_prop(sc);
568 device_printf(sc->dev, "can't set turbo\n");
572 /* result 0=non-turbo, 1=turbo */
573 value = (int)msg->body.resp.level;
574 DPRINTF("level = %d\n", value);
579 bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc,
582 struct msg_get_voltage *msg;
597 * u32: value (offset from 1.2V in units of 0.025V)
600 /* using DMA buffer for VC */
601 msg = (struct msg_get_voltage *)sc->dma_buf;
602 if (sizeof(*msg) > sc->dma_size) {
603 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
604 sizeof(*msg), sc->dma_size);
608 /* setup single tag buffer */
609 memset(msg, 0, sizeof(*msg));
610 msg->hdr.buf_size = sizeof(*msg);
611 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
612 msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_VOLTAGE;
613 msg->tag_hdr.val_buf_size = sizeof(msg->body);
614 msg->tag_hdr.val_len = sizeof(msg->body.req);
615 msg->body.req.voltage_id = voltage_id;
618 /* call mailbox property */
619 err = bcm2835_mbox_call_prop(sc);
621 device_printf(sc->dev, "can't get voltage\n");
625 /* result (offset from 1.2V) */
626 value = (int)msg->body.resp.value;
627 DPRINTF("value = %d\n", value);
632 bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc,
635 struct msg_get_max_voltage *msg;
650 * u32: value (offset from 1.2V in units of 0.025V)
653 /* using DMA buffer for VC */
654 msg = (struct msg_get_max_voltage *)sc->dma_buf;
655 if (sizeof(*msg) > sc->dma_size) {
656 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
657 sizeof(*msg), sc->dma_size);
661 /* setup single tag buffer */
662 memset(msg, 0, sizeof(*msg));
663 msg->hdr.buf_size = sizeof(*msg);
664 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
665 msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_VOLTAGE;
666 msg->tag_hdr.val_buf_size = sizeof(msg->body);
667 msg->tag_hdr.val_len = sizeof(msg->body.req);
668 msg->body.req.voltage_id = voltage_id;
671 /* call mailbox property */
672 err = bcm2835_mbox_call_prop(sc);
674 device_printf(sc->dev, "can't get max voltage\n");
678 /* result (offset from 1.2V) */
679 value = (int)msg->body.resp.value;
680 DPRINTF("value = %d\n", value);
684 bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc,
687 struct msg_get_min_voltage *msg;
702 * u32: value (offset from 1.2V in units of 0.025V)
705 /* using DMA buffer for VC */
706 msg = (struct msg_get_min_voltage *)sc->dma_buf;
707 if (sizeof(*msg) > sc->dma_size) {
708 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
709 sizeof(*msg), sc->dma_size);
713 /* setup single tag buffer */
714 memset(msg, 0, sizeof(*msg));
715 msg->hdr.buf_size = sizeof(*msg);
716 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
717 msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_VOLTAGE;
718 msg->tag_hdr.val_buf_size = sizeof(msg->body);
719 msg->tag_hdr.val_len = sizeof(msg->body.req);
720 msg->body.req.voltage_id = voltage_id;
723 /* call mailbox property */
724 err = bcm2835_mbox_call_prop(sc);
726 device_printf(sc->dev, "can't get min voltage\n");
730 /* result (offset from 1.2V) */
731 value = (int)msg->body.resp.value;
732 DPRINTF("value = %d\n", value);
737 bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc,
738 uint32_t voltage_id, int32_t value)
740 struct msg_set_voltage *msg;
750 * u32: value (offset from 1.2V in units of 0.025V)
755 * u32: value (offset from 1.2V in units of 0.025V)
760 * 0 (1.2 V). Values above 6 are only allowed when force_turbo or
761 * current_limit_override are specified (which set the warranty bit).
763 if (value > MAX_OVER_VOLTAGE || value < MIN_OVER_VOLTAGE) {
764 /* currently not supported */
765 device_printf(sc->dev, "not supported voltage: %d\n", value);
769 /* using DMA buffer for VC */
770 msg = (struct msg_set_voltage *)sc->dma_buf;
771 if (sizeof(*msg) > sc->dma_size) {
772 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
773 sizeof(*msg), sc->dma_size);
777 /* setup single tag buffer */
778 memset(msg, 0, sizeof(*msg));
779 msg->hdr.buf_size = sizeof(*msg);
780 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
781 msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_VOLTAGE;
782 msg->tag_hdr.val_buf_size = sizeof(msg->body);
783 msg->tag_hdr.val_len = sizeof(msg->body.req);
784 msg->body.req.voltage_id = voltage_id;
785 msg->body.req.value = (uint32_t)value;
788 /* call mailbox property */
789 err = bcm2835_mbox_call_prop(sc);
791 device_printf(sc->dev, "can't set voltage\n");
795 /* result (offset from 1.2V) */
796 value = (int)msg->body.resp.value;
797 DPRINTF("value = %d\n", value);
802 bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc)
804 struct msg_get_temperature *msg;
814 * u32: temperature id
818 * u32: temperature id
822 /* using DMA buffer for VC */
823 msg = (struct msg_get_temperature *)sc->dma_buf;
824 if (sizeof(*msg) > sc->dma_size) {
825 device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
826 sizeof(*msg), sc->dma_size);
830 /* setup single tag buffer */
831 memset(msg, 0, sizeof(*msg));
832 msg->hdr.buf_size = sizeof(*msg);
833 msg->hdr.code = BCM2835_MBOX_CODE_REQ;
834 msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TEMPERATURE;
835 msg->tag_hdr.val_buf_size = sizeof(msg->body);
836 msg->tag_hdr.val_len = sizeof(msg->body.req);
837 msg->body.req.temperature_id = 0;
840 /* call mailbox property */
841 err = bcm2835_mbox_call_prop(sc);
843 device_printf(sc->dev, "can't get temperature\n");
847 /* result (temperature of degree C) */
848 value = (int)msg->body.resp.value;
849 DPRINTF("value = %d\n", value);
856 sysctl_bcm2835_cpufreq_arm_freq(SYSCTL_HANDLER_ARGS)
858 struct bcm2835_cpufreq_softc *sc = arg1;
862 /* get realtime value */
864 val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM);
866 if (val == MSG_ERROR)
869 err = sysctl_handle_int(oidp, &val, 0, req);
870 if (err || !req->newptr) /* error || read request */
875 err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
878 if (err == MSG_ERROR) {
879 device_printf(sc->dev, "set clock arm_freq error\n");
882 DELAY(TRANSITION_LATENCY);
888 sysctl_bcm2835_cpufreq_core_freq(SYSCTL_HANDLER_ARGS)
890 struct bcm2835_cpufreq_softc *sc = arg1;
894 /* get realtime value */
896 val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE);
898 if (val == MSG_ERROR)
901 err = sysctl_handle_int(oidp, &val, 0, req);
902 if (err || !req->newptr) /* error || read request */
907 err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
909 if (err == MSG_ERROR) {
911 device_printf(sc->dev, "set clock core_freq error\n");
915 DELAY(TRANSITION_LATENCY);
921 sysctl_bcm2835_cpufreq_sdram_freq(SYSCTL_HANDLER_ARGS)
923 struct bcm2835_cpufreq_softc *sc = arg1;
927 /* get realtime value */
929 val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM);
931 if (val == MSG_ERROR)
934 err = sysctl_handle_int(oidp, &val, 0, req);
935 if (err || !req->newptr) /* error || read request */
940 err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM,
943 if (err == MSG_ERROR) {
944 device_printf(sc->dev, "set clock sdram_freq error\n");
947 DELAY(TRANSITION_LATENCY);
953 sysctl_bcm2835_cpufreq_turbo(SYSCTL_HANDLER_ARGS)
955 struct bcm2835_cpufreq_softc *sc = arg1;
959 /* get realtime value */
961 val = bcm2835_cpufreq_get_turbo(sc);
963 if (val == MSG_ERROR)
966 err = sysctl_handle_int(oidp, &val, 0, req);
967 if (err || !req->newptr) /* error || read request */
972 sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
974 sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;
977 err = bcm2835_cpufreq_set_turbo(sc, sc->turbo_mode);
979 if (err == MSG_ERROR) {
980 device_printf(sc->dev, "set turbo error\n");
983 DELAY(TRANSITION_LATENCY);
989 sysctl_bcm2835_cpufreq_voltage_core(SYSCTL_HANDLER_ARGS)
991 struct bcm2835_cpufreq_softc *sc = arg1;
995 /* get realtime value */
997 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE);
999 if (val == MSG_ERROR)
1002 err = sysctl_handle_int(oidp, &val, 0, req);
1003 if (err || !req->newptr) /* error || read request */
1007 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1009 sc->voltage_core = val;
1012 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE,
1015 if (err == MSG_ERROR) {
1016 device_printf(sc->dev, "set voltage core error\n");
1019 DELAY(TRANSITION_LATENCY);
1025 sysctl_bcm2835_cpufreq_voltage_sdram_c(SYSCTL_HANDLER_ARGS)
1027 struct bcm2835_cpufreq_softc *sc = arg1;
1031 /* get realtime value */
1033 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
1035 if (val == MSG_ERROR)
1038 err = sysctl_handle_int(oidp, &val, 0, req);
1039 if (err || !req->newptr) /* error || read request */
1043 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1045 sc->voltage_sdram_c = val;
1048 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C,
1049 sc->voltage_sdram_c);
1051 if (err == MSG_ERROR) {
1052 device_printf(sc->dev, "set voltage sdram_c error\n");
1055 DELAY(TRANSITION_LATENCY);
1061 sysctl_bcm2835_cpufreq_voltage_sdram_i(SYSCTL_HANDLER_ARGS)
1063 struct bcm2835_cpufreq_softc *sc = arg1;
1067 /* get realtime value */
1069 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
1071 if (val == MSG_ERROR)
1074 err = sysctl_handle_int(oidp, &val, 0, req);
1075 if (err || !req->newptr) /* error || read request */
1079 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1081 sc->voltage_sdram_i = val;
1084 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I,
1085 sc->voltage_sdram_i);
1087 if (err == MSG_ERROR) {
1088 device_printf(sc->dev, "set voltage sdram_i error\n");
1091 DELAY(TRANSITION_LATENCY);
1097 sysctl_bcm2835_cpufreq_voltage_sdram_p(SYSCTL_HANDLER_ARGS)
1099 struct bcm2835_cpufreq_softc *sc = arg1;
1103 /* get realtime value */
1105 val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
1107 if (val == MSG_ERROR)
1110 err = sysctl_handle_int(oidp, &val, 0, req);
1111 if (err || !req->newptr) /* error || read request */
1115 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1117 sc->voltage_sdram_p = val;
1120 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P,
1121 sc->voltage_sdram_p);
1123 if (err == MSG_ERROR) {
1124 device_printf(sc->dev, "set voltage sdram_p error\n");
1127 DELAY(TRANSITION_LATENCY);
1133 sysctl_bcm2835_cpufreq_voltage_sdram(SYSCTL_HANDLER_ARGS)
1135 struct bcm2835_cpufreq_softc *sc = arg1;
1139 /* multiple write only */
1143 err = sysctl_handle_int(oidp, &val, 0, req);
1148 if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
1150 sc->voltage_sdram = val;
1153 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C,
1155 if (err == MSG_ERROR) {
1157 device_printf(sc->dev, "set voltage sdram_c error\n");
1160 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I,
1162 if (err == MSG_ERROR) {
1164 device_printf(sc->dev, "set voltage sdram_i error\n");
1167 err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P,
1169 if (err == MSG_ERROR) {
1171 device_printf(sc->dev, "set voltage sdram_p error\n");
1175 DELAY(TRANSITION_LATENCY);
1181 sysctl_bcm2835_cpufreq_temperature(SYSCTL_HANDLER_ARGS)
1183 struct bcm2835_cpufreq_softc *sc = arg1;
1187 /* get realtime value */
1189 val = bcm2835_cpufreq_get_temperature(sc);
1191 if (val == MSG_ERROR)
1194 err = sysctl_handle_int(oidp, &val, 0, req);
1195 if (err || !req->newptr) /* error || read request */
1203 sysctl_bcm2835_devcpu_temperature(SYSCTL_HANDLER_ARGS)
1205 struct bcm2835_cpufreq_softc *sc = arg1;
1209 /* get realtime value */
1211 val = bcm2835_cpufreq_get_temperature(sc);
1213 if (val == MSG_ERROR)
1216 /* 1/1000 celsius (raw) to 1/10 kelvin */
1217 val = val / 100 + TZ_ZEROC;
1219 err = sysctl_handle_int(oidp, &val, 0, req);
1220 if (err || !req->newptr) /* error || read request */
1229 bcm2835_cpufreq_init(void *arg)
1231 struct bcm2835_cpufreq_softc *sc = arg;
1232 struct sysctl_ctx_list *ctx;
1234 int arm_freq, core_freq, sdram_freq;
1235 int arm_max_freq, arm_min_freq, core_max_freq, core_min_freq;
1236 int sdram_max_freq, sdram_min_freq;
1237 int voltage_core, voltage_sdram_c, voltage_sdram_i, voltage_sdram_p;
1238 int max_voltage_core, min_voltage_core;
1239 int max_voltage_sdram_c, min_voltage_sdram_c;
1240 int max_voltage_sdram_i, min_voltage_sdram_i;
1241 int max_voltage_sdram_p, min_voltage_sdram_p;
1242 int turbo, temperature;
1247 arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
1248 BCM2835_MBOX_CLOCK_ID_ARM);
1249 core_freq = bcm2835_cpufreq_get_clock_rate(sc,
1250 BCM2835_MBOX_CLOCK_ID_CORE);
1251 sdram_freq = bcm2835_cpufreq_get_clock_rate(sc,
1252 BCM2835_MBOX_CLOCK_ID_SDRAM);
1255 arm_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
1256 BCM2835_MBOX_CLOCK_ID_ARM);
1257 arm_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
1258 BCM2835_MBOX_CLOCK_ID_ARM);
1259 core_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
1260 BCM2835_MBOX_CLOCK_ID_CORE);
1261 core_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
1262 BCM2835_MBOX_CLOCK_ID_CORE);
1263 sdram_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
1264 BCM2835_MBOX_CLOCK_ID_SDRAM);
1265 sdram_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
1266 BCM2835_MBOX_CLOCK_ID_SDRAM);
1269 turbo = bcm2835_cpufreq_get_turbo(sc);
1271 sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
1273 sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;
1276 voltage_core = bcm2835_cpufreq_get_voltage(sc,
1277 BCM2835_MBOX_VOLTAGE_ID_CORE);
1278 voltage_sdram_c = bcm2835_cpufreq_get_voltage(sc,
1279 BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
1280 voltage_sdram_i = bcm2835_cpufreq_get_voltage(sc,
1281 BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
1282 voltage_sdram_p = bcm2835_cpufreq_get_voltage(sc,
1283 BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
1285 /* current values (offset from 1.2V) */
1286 sc->voltage_core = voltage_core;
1287 sc->voltage_sdram = voltage_sdram_c;
1288 sc->voltage_sdram_c = voltage_sdram_c;
1289 sc->voltage_sdram_i = voltage_sdram_i;
1290 sc->voltage_sdram_p = voltage_sdram_p;
1292 /* max/min voltage */
1293 max_voltage_core = bcm2835_cpufreq_get_max_voltage(sc,
1294 BCM2835_MBOX_VOLTAGE_ID_CORE);
1295 min_voltage_core = bcm2835_cpufreq_get_min_voltage(sc,
1296 BCM2835_MBOX_VOLTAGE_ID_CORE);
1297 max_voltage_sdram_c = bcm2835_cpufreq_get_max_voltage(sc,
1298 BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
1299 max_voltage_sdram_i = bcm2835_cpufreq_get_max_voltage(sc,
1300 BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
1301 max_voltage_sdram_p = bcm2835_cpufreq_get_max_voltage(sc,
1302 BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
1303 min_voltage_sdram_c = bcm2835_cpufreq_get_min_voltage(sc,
1304 BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
1305 min_voltage_sdram_i = bcm2835_cpufreq_get_min_voltage(sc,
1306 BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
1307 min_voltage_sdram_p = bcm2835_cpufreq_get_min_voltage(sc,
1308 BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
1311 temperature = bcm2835_cpufreq_get_temperature(sc);
1314 if (cpufreq_verbose || bootverbose) {
1315 device_printf(sc->dev, "Boot settings:\n");
1316 device_printf(sc->dev,
1317 "current ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
1318 HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
1319 (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");
1321 device_printf(sc->dev,
1322 "max/min ARM %d/%dMHz, Core %d/%dMHz, SDRAM %d/%dMHz\n",
1323 HZ2MHZ(arm_max_freq), HZ2MHZ(arm_min_freq),
1324 HZ2MHZ(core_max_freq), HZ2MHZ(core_min_freq),
1325 HZ2MHZ(sdram_max_freq), HZ2MHZ(sdram_min_freq));
1327 device_printf(sc->dev,
1328 "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, "
1330 OFFSET2MVOLT(voltage_core), OFFSET2MVOLT(voltage_sdram_c),
1331 OFFSET2MVOLT(voltage_sdram_i),
1332 OFFSET2MVOLT(voltage_sdram_p));
1334 device_printf(sc->dev,
1335 "max/min Core %d/%dmV, SDRAM_C %d/%dmV, SDRAM_I %d/%dmV, "
1336 "SDRAM_P %d/%dmV\n",
1337 OFFSET2MVOLT(max_voltage_core),
1338 OFFSET2MVOLT(min_voltage_core),
1339 OFFSET2MVOLT(max_voltage_sdram_c),
1340 OFFSET2MVOLT(min_voltage_sdram_c),
1341 OFFSET2MVOLT(max_voltage_sdram_i),
1342 OFFSET2MVOLT(min_voltage_sdram_i),
1343 OFFSET2MVOLT(max_voltage_sdram_p),
1344 OFFSET2MVOLT(min_voltage_sdram_p));
1346 device_printf(sc->dev,
1347 "Temperature %d.%dC\n", (temperature / 1000),
1348 (temperature % 1000) / 100);
1349 } else { /* !cpufreq_verbose && !bootverbose */
1350 device_printf(sc->dev,
1351 "ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
1352 HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
1353 (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");
1356 /* keep in softc (MHz/mV) */
1357 sc->arm_max_freq = HZ2MHZ(arm_max_freq);
1358 sc->arm_min_freq = HZ2MHZ(arm_min_freq);
1359 sc->core_max_freq = HZ2MHZ(core_max_freq);
1360 sc->core_min_freq = HZ2MHZ(core_min_freq);
1361 sc->sdram_max_freq = HZ2MHZ(sdram_max_freq);
1362 sc->sdram_min_freq = HZ2MHZ(sdram_min_freq);
1363 sc->max_voltage_core = OFFSET2MVOLT(max_voltage_core);
1364 sc->min_voltage_core = OFFSET2MVOLT(min_voltage_core);
1366 /* if turbo is on, set to max values */
1367 if (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) {
1368 bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
1370 DELAY(TRANSITION_LATENCY);
1371 bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
1373 DELAY(TRANSITION_LATENCY);
1374 bcm2835_cpufreq_set_clock_rate(sc,
1375 BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_max_freq);
1376 DELAY(TRANSITION_LATENCY);
1378 bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
1380 DELAY(TRANSITION_LATENCY);
1381 bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
1383 DELAY(TRANSITION_LATENCY);
1384 bcm2835_cpufreq_set_clock_rate(sc,
1385 BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_min_freq);
1386 DELAY(TRANSITION_LATENCY);
1391 /* add human readable temperature to dev.cpu node */
1392 cpu = device_get_parent(sc->dev);
1394 ctx = device_get_sysctl_ctx(cpu);
1395 SYSCTL_ADD_PROC(ctx,
1396 SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)), OID_AUTO,
1397 "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
1398 sysctl_bcm2835_devcpu_temperature, "IK",
1399 "Current SoC temperature");
1402 /* release this hook (continue boot) */
1403 config_intrhook_disestablish(&sc->init_hook);
1407 bcm2835_cpufreq_identify(driver_t *driver, device_t parent)
1410 DPRINTF("driver=%p, parent=%p\n", driver, parent);
1411 if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL)
1413 if (BUS_ADD_CHILD(parent, 0, "bcm2835_cpufreq", -1) == NULL)
1414 device_printf(parent, "add child failed\n");
1418 bcm2835_cpufreq_probe(device_t dev)
1421 device_set_desc(dev, "CPU Frequency Control");
1426 bcm2835_cpufreq_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
1432 addr = (bus_addr_t *)arg;
1433 *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
1437 bcm2835_cpufreq_attach(device_t dev)
1439 struct bcm2835_cpufreq_softc *sc;
1440 struct sysctl_oid *oid;
1444 sc = device_get_softc(dev);
1447 /* initial values */
1448 sc->arm_max_freq = -1;
1449 sc->arm_min_freq = -1;
1450 sc->core_max_freq = -1;
1451 sc->core_min_freq = -1;
1452 sc->sdram_max_freq = -1;
1453 sc->sdram_min_freq = -1;
1454 sc->max_voltage_core = 0;
1455 sc->min_voltage_core = 0;
1457 /* create VC mbox buffer */
1458 sc->dma_size = PAGE_SIZE;
1459 err = bus_dma_tag_create(
1460 bus_get_dma_tag(sc->dev),
1461 PAGE_SIZE, 0, /* alignment, boundary */
1462 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
1463 BUS_SPACE_MAXADDR, /* highaddr */
1464 NULL, NULL, /* filter, filterarg */
1465 sc->dma_size, 1, /* maxsize, nsegments */
1466 sc->dma_size, 0, /* maxsegsize, flags */
1467 NULL, NULL, /* lockfunc, lockarg */
1470 device_printf(dev, "can't create DMA tag\n");
1474 err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->dma_buf, 0,
1477 bus_dma_tag_destroy(sc->dma_tag);
1478 device_printf(dev, "can't allocate dmamem\n");
1482 err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->dma_buf,
1483 sc->dma_size, bcm2835_cpufreq_cb, &sc->dma_phys, 0);
1485 bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
1486 bus_dma_tag_destroy(sc->dma_tag);
1487 device_printf(dev, "can't load DMA map\n");
1490 /* OK, ready to use VC buffer */
1492 /* setup sysctl at first device */
1493 if (device_get_unit(dev) == 0) {
1494 sysctl_ctx_init(&bcm2835_sysctl_ctx);
1495 /* create node for hw.cpufreq */
1496 oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx,
1497 SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq",
1498 CTLFLAG_RD, NULL, "");
1500 /* Frequency (Hz) */
1501 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1502 OID_AUTO, "arm_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1503 sysctl_bcm2835_cpufreq_arm_freq, "IU",
1504 "ARM frequency (Hz)");
1505 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1506 OID_AUTO, "core_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1507 sysctl_bcm2835_cpufreq_core_freq, "IU",
1508 "Core frequency (Hz)");
1509 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1510 OID_AUTO, "sdram_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1511 sysctl_bcm2835_cpufreq_sdram_freq, "IU",
1512 "SDRAM frequency (Hz)");
1515 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1516 OID_AUTO, "turbo", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1517 sysctl_bcm2835_cpufreq_turbo, "IU",
1518 "Disables dynamic clocking");
1520 /* Voltage (offset from 1.2V in units of 0.025V) */
1521 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1522 OID_AUTO, "voltage_core", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
1523 sysctl_bcm2835_cpufreq_voltage_core, "I",
1524 "ARM/GPU core voltage"
1525 "(offset from 1.2V in units of 0.025V)");
1526 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1527 OID_AUTO, "voltage_sdram", CTLTYPE_INT | CTLFLAG_WR, sc,
1528 0, sysctl_bcm2835_cpufreq_voltage_sdram, "I",
1529 "SDRAM voltage (offset from 1.2V in units of 0.025V)");
1531 /* Voltage individual SDRAM */
1532 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1533 OID_AUTO, "voltage_sdram_c", CTLTYPE_INT | CTLFLAG_RW, sc,
1534 0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I",
1535 "SDRAM controller voltage"
1536 "(offset from 1.2V in units of 0.025V)");
1537 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1538 OID_AUTO, "voltage_sdram_i", CTLTYPE_INT | CTLFLAG_RW, sc,
1539 0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I",
1540 "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)");
1541 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1542 OID_AUTO, "voltage_sdram_p", CTLTYPE_INT | CTLFLAG_RW, sc,
1543 0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I",
1544 "SDRAM phy voltage (offset from 1.2V in units of 0.025V)");
1547 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
1548 OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
1549 sysctl_bcm2835_cpufreq_temperature, "I",
1550 "SoC temperature (thousandths of a degree C)");
1554 sema_init(&vc_sema, 1, "vcsema");
1556 /* register callback for using mbox when interrupts are enabled */
1557 sc->init_hook.ich_func = bcm2835_cpufreq_init;
1558 sc->init_hook.ich_arg = sc;
1560 if (config_intrhook_establish(&sc->init_hook) != 0) {
1561 bus_dmamap_unload(sc->dma_tag, sc->dma_map);
1562 bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
1563 bus_dma_tag_destroy(sc->dma_tag);
1564 device_printf(dev, "config_intrhook_establish failed\n");
1568 /* this device is controlled by cpufreq(4) */
1569 cpufreq_register(dev);
1575 bcm2835_cpufreq_detach(device_t dev)
1577 struct bcm2835_cpufreq_softc *sc;
1579 sc = device_get_softc(dev);
1581 sema_destroy(&vc_sema);
1583 if (sc->dma_phys != 0)
1584 bus_dmamap_unload(sc->dma_tag, sc->dma_map);
1585 if (sc->dma_buf != NULL)
1586 bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
1587 if (sc->dma_tag != NULL)
1588 bus_dma_tag_destroy(sc->dma_tag);
1590 return (cpufreq_unregister(dev));
1594 bcm2835_cpufreq_set(device_t dev, const struct cf_setting *cf)
1596 struct bcm2835_cpufreq_softc *sc;
1597 uint32_t rate_hz, rem;
1598 int cur_freq, resp_freq, arm_freq, min_freq, core_freq;
1600 if (cf == NULL || cf->freq < 0)
1603 sc = device_get_softc(dev);
1605 /* setting clock (Hz) */
1606 rate_hz = (uint32_t)MHZ2HZ(cf->freq);
1607 rem = rate_hz % HZSTEP;
1612 /* adjust min freq */
1613 min_freq = sc->arm_min_freq;
1614 if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON)
1615 if (min_freq > cpufreq_lowest_freq)
1616 min_freq = cpufreq_lowest_freq;
1618 if (rate_hz < MHZ2HZ(min_freq) || rate_hz > MHZ2HZ(sc->arm_max_freq))
1621 /* set new value and verify it */
1623 cur_freq = bcm2835_cpufreq_get_clock_rate(sc,
1624 BCM2835_MBOX_CLOCK_ID_ARM);
1625 resp_freq = bcm2835_cpufreq_set_clock_rate(sc,
1626 BCM2835_MBOX_CLOCK_ID_ARM, rate_hz);
1627 DELAY(TRANSITION_LATENCY);
1628 arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
1629 BCM2835_MBOX_CLOCK_ID_ARM);
1632 * if non-turbo and lower than or equal min_freq,
1633 * clock down core and sdram to default first.
1635 if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON) {
1636 core_freq = bcm2835_cpufreq_get_clock_rate(sc,
1637 BCM2835_MBOX_CLOCK_ID_CORE);
1638 if (rate_hz > MHZ2HZ(sc->arm_min_freq)) {
1639 bcm2835_cpufreq_set_clock_rate(sc,
1640 BCM2835_MBOX_CLOCK_ID_CORE,
1641 MHZ2HZ(sc->core_max_freq));
1642 DELAY(TRANSITION_LATENCY);
1643 bcm2835_cpufreq_set_clock_rate(sc,
1644 BCM2835_MBOX_CLOCK_ID_SDRAM,
1645 MHZ2HZ(sc->sdram_max_freq));
1646 DELAY(TRANSITION_LATENCY);
1648 if (sc->core_min_freq < DEFAULT_CORE_FREQUENCY &&
1649 core_freq > DEFAULT_CORE_FREQUENCY) {
1650 /* first, down to 250, then down to min */
1651 DELAY(TRANSITION_LATENCY);
1652 bcm2835_cpufreq_set_clock_rate(sc,
1653 BCM2835_MBOX_CLOCK_ID_CORE,
1654 MHZ2HZ(DEFAULT_CORE_FREQUENCY));
1655 DELAY(TRANSITION_LATENCY);
1656 /* reset core voltage */
1657 bcm2835_cpufreq_set_voltage(sc,
1658 BCM2835_MBOX_VOLTAGE_ID_CORE, 0);
1659 DELAY(TRANSITION_LATENCY);
1661 bcm2835_cpufreq_set_clock_rate(sc,
1662 BCM2835_MBOX_CLOCK_ID_CORE,
1663 MHZ2HZ(sc->core_min_freq));
1664 DELAY(TRANSITION_LATENCY);
1665 bcm2835_cpufreq_set_clock_rate(sc,
1666 BCM2835_MBOX_CLOCK_ID_SDRAM,
1667 MHZ2HZ(sc->sdram_min_freq));
1668 DELAY(TRANSITION_LATENCY);
1674 if (resp_freq < 0 || arm_freq < 0 || resp_freq != arm_freq) {
1675 device_printf(dev, "wrong freq\n");
1678 DPRINTF("cpufreq: %d -> %d\n", cur_freq, arm_freq);
1684 bcm2835_cpufreq_get(device_t dev, struct cf_setting *cf)
1686 struct bcm2835_cpufreq_softc *sc;
1692 sc = device_get_softc(dev);
1693 memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf));
1696 /* get cuurent value */
1698 arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
1699 BCM2835_MBOX_CLOCK_ID_ARM);
1702 device_printf(dev, "can't get clock\n");
1706 /* CPU clock in MHz or 100ths of a percent. */
1707 cf->freq = HZ2MHZ(arm_freq);
1708 /* Voltage in mV. */
1709 cf->volts = CPUFREQ_VAL_UNKNOWN;
1710 /* Power consumed in mW. */
1711 cf->power = CPUFREQ_VAL_UNKNOWN;
1712 /* Transition latency in us. */
1713 cf->lat = TRANSITION_LATENCY;
1714 /* Driver providing this setting. */
1721 bcm2835_cpufreq_make_freq_list(device_t dev, struct cf_setting *sets,
1724 struct bcm2835_cpufreq_softc *sc;
1725 int freq, min_freq, volts, rem;
1728 sc = device_get_softc(dev);
1729 freq = sc->arm_max_freq;
1730 min_freq = sc->arm_min_freq;
1732 /* adjust head freq to STEP */
1733 rem = freq % MHZSTEP;
1735 if (freq < min_freq)
1738 /* if non-turbo, add extra low freq */
1739 if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON)
1740 if (min_freq > cpufreq_lowest_freq)
1741 min_freq = cpufreq_lowest_freq;
1743 /* from freq to min_freq */
1744 for (idx = 0; idx < *count && freq >= min_freq; idx++) {
1745 if (freq > sc->arm_min_freq)
1746 volts = sc->max_voltage_core;
1748 volts = sc->min_voltage_core;
1749 sets[idx].freq = freq;
1750 sets[idx].volts = volts;
1751 sets[idx].lat = TRANSITION_LATENCY;
1752 sets[idx].dev = dev;
1761 bcm2835_cpufreq_settings(device_t dev, struct cf_setting *sets, int *count)
1763 struct bcm2835_cpufreq_softc *sc;
1765 if (sets == NULL || count == NULL)
1768 sc = device_get_softc(dev);
1769 if (sc->arm_min_freq < 0 || sc->arm_max_freq < 0) {
1770 printf("device is not configured\n");
1774 /* fill data with unknown value */
1775 memset(sets, CPUFREQ_VAL_UNKNOWN, sizeof(*sets) * (*count));
1776 /* create new array up to count */
1777 bcm2835_cpufreq_make_freq_list(dev, sets, count);
1783 bcm2835_cpufreq_type(device_t dev, int *type)
1788 *type = CPUFREQ_TYPE_ABSOLUTE;
1793 static device_method_t bcm2835_cpufreq_methods[] = {
1794 /* Device interface */
1795 DEVMETHOD(device_identify, bcm2835_cpufreq_identify),
1796 DEVMETHOD(device_probe, bcm2835_cpufreq_probe),
1797 DEVMETHOD(device_attach, bcm2835_cpufreq_attach),
1798 DEVMETHOD(device_detach, bcm2835_cpufreq_detach),
1800 /* cpufreq interface */
1801 DEVMETHOD(cpufreq_drv_set, bcm2835_cpufreq_set),
1802 DEVMETHOD(cpufreq_drv_get, bcm2835_cpufreq_get),
1803 DEVMETHOD(cpufreq_drv_settings, bcm2835_cpufreq_settings),
1804 DEVMETHOD(cpufreq_drv_type, bcm2835_cpufreq_type),
1809 static devclass_t bcm2835_cpufreq_devclass;
1810 static driver_t bcm2835_cpufreq_driver = {
1812 bcm2835_cpufreq_methods,
1813 sizeof(struct bcm2835_cpufreq_softc),
1816 DRIVER_MODULE(bcm2835_cpufreq, cpu, bcm2835_cpufreq_driver,
1817 bcm2835_cpufreq_devclass, 0, 0);