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/param.h>
29 #include <sys/systm.h>
32 #include <sys/kernel.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/mutex.h>
38 #include <sys/sysctl.h>
40 #include <machine/bus.h>
41 #include <machine/cpu.h>
42 #include <machine/intr.h>
44 #include <dev/ofw/ofw_bus.h>
45 #include <dev/ofw/ofw_bus_subr.h>
47 #include <arm/broadcom/bcm2835/bcm2835_firmware.h>
48 #include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
50 #include "cpufreq_if.h"
53 #define DPRINTF(fmt, ...) do { \
54 printf("%s:%u: ", __func__, __LINE__); \
55 printf(fmt, ##__VA_ARGS__); \
58 #define DPRINTF(fmt, ...)
61 #define HZ2MHZ(freq) ((freq) / (1000 * 1000))
62 #define MHZ2HZ(freq) ((freq) * (1000 * 1000))
64 #define OFFSET2MVOLT(val) (((val) / 1000))
65 #define MVOLT2OFFSET(val) (((val) * 1000))
66 #define DEFAULT_ARM_FREQUENCY 600
67 #define DEFAULT_LOWEST_FREQ 600
68 #define DEFAULT_CORE_FREQUENCY 250
69 #define DEFAULT_SDRAM_FREQUENCY 400
70 #define TRANSITION_LATENCY 1000
71 #define MIN_OVER_VOLTAGE -16
72 #define MAX_OVER_VOLTAGE 6
73 #define MSG_ERROR -999999999
75 #define HZSTEP (MHZ2HZ(MHZSTEP))
78 #define VC_LOCK(sc) do { \
79 sema_wait(&vc_sema); \
81 #define VC_UNLOCK(sc) do { \
82 sema_post(&vc_sema); \
85 /* ARM->VC mailbox property semaphore */
86 static struct sema vc_sema
;
88 static struct sysctl_ctx_list bcm2835_sysctl_ctx
;
90 struct bcm2835_cpufreq_softc
{
100 int min_voltage_core
;
102 /* the values written in mbox */
110 /* initial hook for waiting mbox intr */
111 struct intr_config_hook init_hook
;
114 static struct ofw_compat_data compat_data
[] = {
115 { "broadcom,bcm2835-vc", 1 },
116 { "broadcom,bcm2708-vc", 1 },
117 { "brcm,bcm2709", 1 },
118 { "brcm,bcm2835", 1 },
119 { "brcm,bcm2836", 1 },
120 { "brcm,bcm2837", 1 },
121 { "brcm,bcm2711", 1 },
125 static int cpufreq_verbose
= 0;
126 TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose
);
127 static int cpufreq_lowest_freq
= DEFAULT_LOWEST_FREQ
;
128 TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq
);
132 bcm2835_dump(const void *data
, int len
)
134 const uint8_t *p
= (const uint8_t*)data
;
137 printf("dump @ %p:\n", data
);
138 for (i
= 0; i
< len
; i
++) {
139 printf("%2.2x ", p
[i
]);
150 bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc
*sc
,
153 union msg_get_clock_rate_body msg
;
171 /* setup single tag buffer */
172 memset(&msg
, 0, sizeof(msg
));
173 msg
.req
.clock_id
= clock_id
;
175 /* call mailbox property */
176 err
= bcm2835_firmware_property(sc
->firmware
,
177 BCM2835_FIRMWARE_TAG_GET_CLOCK_RATE
, &msg
, sizeof(msg
));
179 device_printf(sc
->dev
, "can't get clock rate (id=%u)\n",
185 rate
= (int)msg
.resp
.rate_hz
;
186 DPRINTF("clock = %d(Hz)\n", rate
);
191 bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc
*sc
,
194 union msg_get_clock_rate_body msg
;
212 /* setup single tag buffer */
213 memset(&msg
, 0, sizeof(msg
));
214 msg
.req
.clock_id
= clock_id
;
216 /* call mailbox property */
217 err
= bcm2835_firmware_property(sc
->firmware
,
218 BCM2835_FIRMWARE_TAG_GET_MAX_CLOCK_RATE
, &msg
, sizeof(msg
));
220 device_printf(sc
->dev
, "can't get max clock rate (id=%u)\n",
226 rate
= (int)msg
.resp
.rate_hz
;
227 DPRINTF("clock = %d(Hz)\n", rate
);
232 bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc
*sc
,
235 union msg_get_clock_rate_body msg
;
253 /* setup single tag buffer */
254 memset(&msg
, 0, sizeof(msg
));
255 msg
.req
.clock_id
= clock_id
;
257 /* call mailbox property */
258 err
= bcm2835_firmware_property(sc
->firmware
,
259 BCM2835_FIRMWARE_TAG_GET_MIN_CLOCK_RATE
, &msg
, sizeof(msg
));
261 device_printf(sc
->dev
, "can't get min clock rate (id=%u)\n",
267 rate
= (int)msg
.resp
.rate_hz
;
268 DPRINTF("clock = %d(Hz)\n", rate
);
273 bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc
*sc
,
274 uint32_t clock_id
, uint32_t rate_hz
)
276 union msg_set_clock_rate_body msg
;
295 /* setup single tag buffer */
296 memset(&msg
, 0, sizeof(msg
));
297 msg
.req
.clock_id
= clock_id
;
298 msg
.req
.rate_hz
= rate_hz
;
300 /* call mailbox property */
301 err
= bcm2835_firmware_property(sc
->firmware
,
302 BCM2835_FIRMWARE_TAG_SET_CLOCK_RATE
, &msg
, sizeof(msg
));
304 device_printf(sc
->dev
, "can't set clock rate (id=%u)\n",
309 /* workaround for core clock */
310 if (clock_id
== BCM2835_FIRMWARE_CLOCK_ID_CORE
) {
311 /* for safety (may change voltage without changing clock) */
312 DELAY(TRANSITION_LATENCY
);
315 * XXX: the core clock is unable to change at once,
316 * to change certainly, write it twice now.
319 /* setup single tag buffer */
320 memset(&msg
, 0, sizeof(msg
));
321 msg
.req
.clock_id
= clock_id
;
322 msg
.req
.rate_hz
= rate_hz
;
324 /* call mailbox property */
325 err
= bcm2835_firmware_property(sc
->firmware
,
326 BCM2835_FIRMWARE_TAG_SET_CLOCK_RATE
, &msg
, sizeof(msg
));
328 device_printf(sc
->dev
,
329 "can't set clock rate (id=%u)\n", clock_id
);
335 rate
= (int)msg
.resp
.rate_hz
;
336 DPRINTF("clock = %d(Hz)\n", rate
);
341 bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc
*sc
)
343 union msg_get_turbo_body msg
;
361 /* setup single tag buffer */
362 memset(&msg
, 0, sizeof(msg
));
365 /* call mailbox property */
366 err
= bcm2835_firmware_property(sc
->firmware
,
367 BCM2835_FIRMWARE_TAG_GET_TURBO
, &msg
, sizeof(msg
));
369 device_printf(sc
->dev
, "can't get turbo\n");
373 /* result 0=non-turbo, 1=turbo */
374 level
= (int)msg
.resp
.level
;
375 DPRINTF("level = %d\n", level
);
380 bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc
*sc
, uint32_t level
)
382 union msg_set_turbo_body msg
;
401 /* replace unknown value to OFF */
402 if (level
!= BCM2835_FIRMWARE_TURBO_ON
&&
403 level
!= BCM2835_FIRMWARE_TURBO_OFF
)
404 level
= BCM2835_FIRMWARE_TURBO_OFF
;
406 /* setup single tag buffer */
407 memset(&msg
, 0, sizeof(msg
));
409 msg
.req
.level
= level
;
411 /* call mailbox property */
412 err
= bcm2835_firmware_property(sc
->firmware
,
413 BCM2835_FIRMWARE_TAG_SET_TURBO
, &msg
, sizeof(msg
));
415 device_printf(sc
->dev
, "can't set turbo\n");
419 /* result 0=non-turbo, 1=turbo */
420 value
= (int)msg
.resp
.level
;
421 DPRINTF("level = %d\n", value
);
426 bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc
*sc
,
429 union msg_get_voltage_body msg
;
444 * u32: value (offset from 1.2V in units of 0.025V)
447 /* setup single tag buffer */
448 memset(&msg
, 0, sizeof(msg
));
449 msg
.req
.voltage_id
= voltage_id
;
451 /* call mailbox property */
452 err
= bcm2835_firmware_property(sc
->firmware
,
453 BCM2835_FIRMWARE_TAG_GET_VOLTAGE
, &msg
, sizeof(msg
));
455 device_printf(sc
->dev
, "can't get voltage\n");
459 /* result (offset from 1.2V) */
460 value
= (int)msg
.resp
.value
;
461 DPRINTF("value = %d\n", value
);
466 bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc
*sc
,
469 union msg_get_voltage_body msg
;
484 * u32: value (offset from 1.2V in units of 0.025V)
487 /* setup single tag buffer */
488 memset(&msg
, 0, sizeof(msg
));
489 msg
.req
.voltage_id
= voltage_id
;
491 /* call mailbox property */
492 err
= bcm2835_firmware_property(sc
->firmware
,
493 BCM2835_FIRMWARE_TAG_GET_MAX_VOLTAGE
, &msg
, sizeof(msg
));
495 device_printf(sc
->dev
, "can't get max voltage\n");
499 /* result (offset from 1.2V) */
500 value
= (int)msg
.resp
.value
;
501 DPRINTF("value = %d\n", value
);
505 bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc
*sc
,
508 union msg_get_voltage_body msg
;
523 * u32: value (offset from 1.2V in units of 0.025V)
526 /* setup single tag buffer */
527 memset(&msg
, 0, sizeof(msg
));
528 msg
.req
.voltage_id
= voltage_id
;
530 /* call mailbox property */
531 err
= bcm2835_firmware_property(sc
->firmware
,
532 BCM2835_FIRMWARE_TAG_GET_MIN_VOLTAGE
, &msg
, sizeof(msg
));
534 device_printf(sc
->dev
, "can't get min voltage\n");
538 /* result (offset from 1.2V) */
539 value
= (int)msg
.resp
.value
;
540 DPRINTF("value = %d\n", value
);
545 bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc
*sc
,
546 uint32_t voltage_id
, int32_t value
)
548 union msg_set_voltage_body msg
;
558 * u32: value (offset from 1.2V in units of 0.025V)
563 * u32: value (offset from 1.2V in units of 0.025V)
568 * 0 (1.2 V). Values above 6 are only allowed when force_turbo or
569 * current_limit_override are specified (which set the warranty bit).
571 if (value
> MAX_OVER_VOLTAGE
|| value
< MIN_OVER_VOLTAGE
) {
572 /* currently not supported */
573 device_printf(sc
->dev
, "not supported voltage: %d\n", value
);
577 /* setup single tag buffer */
578 memset(&msg
, 0, sizeof(msg
));
579 msg
.req
.voltage_id
= voltage_id
;
580 msg
.req
.value
= (uint32_t)value
;
582 /* call mailbox property */
583 err
= bcm2835_firmware_property(sc
->firmware
,
584 BCM2835_FIRMWARE_TAG_SET_VOLTAGE
, &msg
, sizeof(msg
));
586 device_printf(sc
->dev
, "can't set voltage\n");
590 /* result (offset from 1.2V) */
591 value
= (int)msg
.resp
.value
;
592 DPRINTF("value = %d\n", value
);
597 bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc
*sc
)
599 union msg_get_temperature_body msg
;
609 * u32: temperature id
613 * u32: temperature id
617 /* setup single tag buffer */
618 memset(&msg
, 0, sizeof(msg
));
619 msg
.req
.temperature_id
= 0;
621 /* call mailbox property */
622 err
= bcm2835_firmware_property(sc
->firmware
,
623 BCM2835_FIRMWARE_TAG_GET_TEMPERATURE
, &msg
, sizeof(msg
));
625 device_printf(sc
->dev
, "can't get temperature\n");
629 /* result (temperature of degree C) */
630 value
= (int)msg
.resp
.value
;
631 DPRINTF("value = %d\n", value
);
636 sysctl_bcm2835_cpufreq_arm_freq(SYSCTL_HANDLER_ARGS
)
638 struct bcm2835_cpufreq_softc
*sc
= arg1
;
642 /* get realtime value */
644 val
= bcm2835_cpufreq_get_clock_rate(sc
, BCM2835_FIRMWARE_CLOCK_ID_ARM
);
646 if (val
== MSG_ERROR
)
649 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
650 if (err
|| !req
->newptr
) /* error || read request */
655 err
= bcm2835_cpufreq_set_clock_rate(sc
, BCM2835_FIRMWARE_CLOCK_ID_ARM
,
658 if (err
== MSG_ERROR
) {
659 device_printf(sc
->dev
, "set clock arm_freq error\n");
662 DELAY(TRANSITION_LATENCY
);
668 sysctl_bcm2835_cpufreq_core_freq(SYSCTL_HANDLER_ARGS
)
670 struct bcm2835_cpufreq_softc
*sc
= arg1
;
674 /* get realtime value */
676 val
= bcm2835_cpufreq_get_clock_rate(sc
,
677 BCM2835_FIRMWARE_CLOCK_ID_CORE
);
679 if (val
== MSG_ERROR
)
682 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
683 if (err
|| !req
->newptr
) /* error || read request */
688 err
= bcm2835_cpufreq_set_clock_rate(sc
, BCM2835_FIRMWARE_CLOCK_ID_CORE
,
690 if (err
== MSG_ERROR
) {
692 device_printf(sc
->dev
, "set clock core_freq error\n");
696 DELAY(TRANSITION_LATENCY
);
702 sysctl_bcm2835_cpufreq_sdram_freq(SYSCTL_HANDLER_ARGS
)
704 struct bcm2835_cpufreq_softc
*sc
= arg1
;
708 /* get realtime value */
710 val
= bcm2835_cpufreq_get_clock_rate(sc
,
711 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
);
713 if (val
== MSG_ERROR
)
716 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
717 if (err
|| !req
->newptr
) /* error || read request */
722 err
= bcm2835_cpufreq_set_clock_rate(sc
,
723 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
, val
);
725 if (err
== MSG_ERROR
) {
726 device_printf(sc
->dev
, "set clock sdram_freq error\n");
729 DELAY(TRANSITION_LATENCY
);
735 sysctl_bcm2835_cpufreq_turbo(SYSCTL_HANDLER_ARGS
)
737 struct bcm2835_cpufreq_softc
*sc
= arg1
;
741 /* get realtime value */
743 val
= bcm2835_cpufreq_get_turbo(sc
);
745 if (val
== MSG_ERROR
)
748 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
749 if (err
|| !req
->newptr
) /* error || read request */
754 sc
->turbo_mode
= BCM2835_FIRMWARE_TURBO_ON
;
756 sc
->turbo_mode
= BCM2835_FIRMWARE_TURBO_OFF
;
759 err
= bcm2835_cpufreq_set_turbo(sc
, sc
->turbo_mode
);
761 if (err
== MSG_ERROR
) {
762 device_printf(sc
->dev
, "set turbo error\n");
765 DELAY(TRANSITION_LATENCY
);
771 sysctl_bcm2835_cpufreq_voltage_core(SYSCTL_HANDLER_ARGS
)
773 struct bcm2835_cpufreq_softc
*sc
= arg1
;
777 /* get realtime value */
779 val
= bcm2835_cpufreq_get_voltage(sc
, BCM2835_FIRMWARE_VOLTAGE_ID_CORE
);
781 if (val
== MSG_ERROR
)
784 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
785 if (err
|| !req
->newptr
) /* error || read request */
789 if (val
> MAX_OVER_VOLTAGE
|| val
< MIN_OVER_VOLTAGE
)
791 sc
->voltage_core
= val
;
794 err
= bcm2835_cpufreq_set_voltage(sc
, BCM2835_FIRMWARE_VOLTAGE_ID_CORE
,
797 if (err
== MSG_ERROR
) {
798 device_printf(sc
->dev
, "set voltage core error\n");
801 DELAY(TRANSITION_LATENCY
);
807 sysctl_bcm2835_cpufreq_voltage_sdram_c(SYSCTL_HANDLER_ARGS
)
809 struct bcm2835_cpufreq_softc
*sc
= arg1
;
813 /* get realtime value */
815 val
= bcm2835_cpufreq_get_voltage(sc
,
816 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C
);
818 if (val
== MSG_ERROR
)
821 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
822 if (err
|| !req
->newptr
) /* error || read request */
826 if (val
> MAX_OVER_VOLTAGE
|| val
< MIN_OVER_VOLTAGE
)
828 sc
->voltage_sdram_c
= val
;
831 err
= bcm2835_cpufreq_set_voltage(sc
,
832 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C
,
833 sc
->voltage_sdram_c
);
835 if (err
== MSG_ERROR
) {
836 device_printf(sc
->dev
, "set voltage sdram_c error\n");
839 DELAY(TRANSITION_LATENCY
);
845 sysctl_bcm2835_cpufreq_voltage_sdram_i(SYSCTL_HANDLER_ARGS
)
847 struct bcm2835_cpufreq_softc
*sc
= arg1
;
851 /* get realtime value */
853 val
= bcm2835_cpufreq_get_voltage(sc
,
854 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I
);
856 if (val
== MSG_ERROR
)
859 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
860 if (err
|| !req
->newptr
) /* error || read request */
864 if (val
> MAX_OVER_VOLTAGE
|| val
< MIN_OVER_VOLTAGE
)
866 sc
->voltage_sdram_i
= val
;
869 err
= bcm2835_cpufreq_set_voltage(sc
,
870 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I
, sc
->voltage_sdram_i
);
872 if (err
== MSG_ERROR
) {
873 device_printf(sc
->dev
, "set voltage sdram_i error\n");
876 DELAY(TRANSITION_LATENCY
);
882 sysctl_bcm2835_cpufreq_voltage_sdram_p(SYSCTL_HANDLER_ARGS
)
884 struct bcm2835_cpufreq_softc
*sc
= arg1
;
888 /* get realtime value */
890 val
= bcm2835_cpufreq_get_voltage(sc
,
891 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P
);
893 if (val
== MSG_ERROR
)
896 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
897 if (err
|| !req
->newptr
) /* error || read request */
901 if (val
> MAX_OVER_VOLTAGE
|| val
< MIN_OVER_VOLTAGE
)
903 sc
->voltage_sdram_p
= val
;
906 err
= bcm2835_cpufreq_set_voltage(sc
,
907 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P
, sc
->voltage_sdram_p
);
909 if (err
== MSG_ERROR
) {
910 device_printf(sc
->dev
, "set voltage sdram_p error\n");
913 DELAY(TRANSITION_LATENCY
);
919 sysctl_bcm2835_cpufreq_voltage_sdram(SYSCTL_HANDLER_ARGS
)
921 struct bcm2835_cpufreq_softc
*sc
= arg1
;
925 /* multiple write only */
929 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
934 if (val
> MAX_OVER_VOLTAGE
|| val
< MIN_OVER_VOLTAGE
)
936 sc
->voltage_sdram
= val
;
939 err
= bcm2835_cpufreq_set_voltage(sc
,
940 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C
, val
);
941 if (err
== MSG_ERROR
) {
943 device_printf(sc
->dev
, "set voltage sdram_c error\n");
946 err
= bcm2835_cpufreq_set_voltage(sc
,
947 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I
, val
);
948 if (err
== MSG_ERROR
) {
950 device_printf(sc
->dev
, "set voltage sdram_i error\n");
953 err
= bcm2835_cpufreq_set_voltage(sc
,
954 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P
, val
);
955 if (err
== MSG_ERROR
) {
957 device_printf(sc
->dev
, "set voltage sdram_p error\n");
961 DELAY(TRANSITION_LATENCY
);
967 sysctl_bcm2835_cpufreq_temperature(SYSCTL_HANDLER_ARGS
)
969 struct bcm2835_cpufreq_softc
*sc
= arg1
;
973 /* get realtime value */
975 val
= bcm2835_cpufreq_get_temperature(sc
);
977 if (val
== MSG_ERROR
)
980 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
981 if (err
|| !req
->newptr
) /* error || read request */
989 sysctl_bcm2835_devcpu_temperature(SYSCTL_HANDLER_ARGS
)
991 struct bcm2835_cpufreq_softc
*sc
= arg1
;
995 /* get realtime value */
997 val
= bcm2835_cpufreq_get_temperature(sc
);
999 if (val
== MSG_ERROR
)
1002 /* 1/1000 celsius (raw) to 1/10 kelvin */
1003 val
= val
/ 100 + TZ_ZEROC
;
1005 err
= sysctl_handle_int(oidp
, &val
, 0, req
);
1006 if (err
|| !req
->newptr
) /* error || read request */
1014 bcm2835_cpufreq_init(void *arg
)
1016 struct bcm2835_cpufreq_softc
*sc
= arg
;
1017 struct sysctl_ctx_list
*ctx
;
1019 int arm_freq
, core_freq
, sdram_freq
;
1020 int arm_max_freq
, arm_min_freq
, core_max_freq
, core_min_freq
;
1021 int sdram_max_freq
, sdram_min_freq
;
1022 int voltage_core
, voltage_sdram_c
, voltage_sdram_i
, voltage_sdram_p
;
1023 int max_voltage_core
, min_voltage_core
;
1024 int max_voltage_sdram_c
, min_voltage_sdram_c
;
1025 int max_voltage_sdram_i
, min_voltage_sdram_i
;
1026 int max_voltage_sdram_p
, min_voltage_sdram_p
;
1027 int turbo
, temperature
;
1032 arm_freq
= bcm2835_cpufreq_get_clock_rate(sc
,
1033 BCM2835_FIRMWARE_CLOCK_ID_ARM
);
1034 core_freq
= bcm2835_cpufreq_get_clock_rate(sc
,
1035 BCM2835_FIRMWARE_CLOCK_ID_CORE
);
1036 sdram_freq
= bcm2835_cpufreq_get_clock_rate(sc
,
1037 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
);
1040 arm_max_freq
= bcm2835_cpufreq_get_max_clock_rate(sc
,
1041 BCM2835_FIRMWARE_CLOCK_ID_ARM
);
1042 arm_min_freq
= bcm2835_cpufreq_get_min_clock_rate(sc
,
1043 BCM2835_FIRMWARE_CLOCK_ID_ARM
);
1044 core_max_freq
= bcm2835_cpufreq_get_max_clock_rate(sc
,
1045 BCM2835_FIRMWARE_CLOCK_ID_CORE
);
1046 core_min_freq
= bcm2835_cpufreq_get_min_clock_rate(sc
,
1047 BCM2835_FIRMWARE_CLOCK_ID_CORE
);
1048 sdram_max_freq
= bcm2835_cpufreq_get_max_clock_rate(sc
,
1049 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
);
1050 sdram_min_freq
= bcm2835_cpufreq_get_min_clock_rate(sc
,
1051 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
);
1054 turbo
= bcm2835_cpufreq_get_turbo(sc
);
1056 sc
->turbo_mode
= BCM2835_FIRMWARE_TURBO_ON
;
1058 sc
->turbo_mode
= BCM2835_FIRMWARE_TURBO_OFF
;
1061 voltage_core
= bcm2835_cpufreq_get_voltage(sc
,
1062 BCM2835_FIRMWARE_VOLTAGE_ID_CORE
);
1063 voltage_sdram_c
= bcm2835_cpufreq_get_voltage(sc
,
1064 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C
);
1065 voltage_sdram_i
= bcm2835_cpufreq_get_voltage(sc
,
1066 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I
);
1067 voltage_sdram_p
= bcm2835_cpufreq_get_voltage(sc
,
1068 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P
);
1070 /* current values (offset from 1.2V) */
1071 sc
->voltage_core
= voltage_core
;
1072 sc
->voltage_sdram
= voltage_sdram_c
;
1073 sc
->voltage_sdram_c
= voltage_sdram_c
;
1074 sc
->voltage_sdram_i
= voltage_sdram_i
;
1075 sc
->voltage_sdram_p
= voltage_sdram_p
;
1077 /* max/min voltage */
1078 max_voltage_core
= bcm2835_cpufreq_get_max_voltage(sc
,
1079 BCM2835_FIRMWARE_VOLTAGE_ID_CORE
);
1080 min_voltage_core
= bcm2835_cpufreq_get_min_voltage(sc
,
1081 BCM2835_FIRMWARE_VOLTAGE_ID_CORE
);
1082 max_voltage_sdram_c
= bcm2835_cpufreq_get_max_voltage(sc
,
1083 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C
);
1084 max_voltage_sdram_i
= bcm2835_cpufreq_get_max_voltage(sc
,
1085 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I
);
1086 max_voltage_sdram_p
= bcm2835_cpufreq_get_max_voltage(sc
,
1087 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P
);
1088 min_voltage_sdram_c
= bcm2835_cpufreq_get_min_voltage(sc
,
1089 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_C
);
1090 min_voltage_sdram_i
= bcm2835_cpufreq_get_min_voltage(sc
,
1091 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_I
);
1092 min_voltage_sdram_p
= bcm2835_cpufreq_get_min_voltage(sc
,
1093 BCM2835_FIRMWARE_VOLTAGE_ID_SDRAM_P
);
1096 temperature
= bcm2835_cpufreq_get_temperature(sc
);
1099 if (cpufreq_verbose
|| bootverbose
) {
1100 device_printf(sc
->dev
, "Boot settings:\n");
1101 device_printf(sc
->dev
,
1102 "current ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
1103 HZ2MHZ(arm_freq
), HZ2MHZ(core_freq
), HZ2MHZ(sdram_freq
),
1104 (sc
->turbo_mode
== BCM2835_FIRMWARE_TURBO_ON
) ? "ON":"OFF");
1106 device_printf(sc
->dev
,
1107 "max/min ARM %d/%dMHz, Core %d/%dMHz, SDRAM %d/%dMHz\n",
1108 HZ2MHZ(arm_max_freq
), HZ2MHZ(arm_min_freq
),
1109 HZ2MHZ(core_max_freq
), HZ2MHZ(core_min_freq
),
1110 HZ2MHZ(sdram_max_freq
), HZ2MHZ(sdram_min_freq
));
1112 device_printf(sc
->dev
,
1113 "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, "
1115 OFFSET2MVOLT(voltage_core
), OFFSET2MVOLT(voltage_sdram_c
),
1116 OFFSET2MVOLT(voltage_sdram_i
),
1117 OFFSET2MVOLT(voltage_sdram_p
));
1119 device_printf(sc
->dev
,
1120 "max/min Core %d/%dmV, SDRAM_C %d/%dmV, SDRAM_I %d/%dmV, "
1121 "SDRAM_P %d/%dmV\n",
1122 OFFSET2MVOLT(max_voltage_core
),
1123 OFFSET2MVOLT(min_voltage_core
),
1124 OFFSET2MVOLT(max_voltage_sdram_c
),
1125 OFFSET2MVOLT(min_voltage_sdram_c
),
1126 OFFSET2MVOLT(max_voltage_sdram_i
),
1127 OFFSET2MVOLT(min_voltage_sdram_i
),
1128 OFFSET2MVOLT(max_voltage_sdram_p
),
1129 OFFSET2MVOLT(min_voltage_sdram_p
));
1131 device_printf(sc
->dev
,
1132 "Temperature %d.%dC\n", (temperature
/ 1000),
1133 (temperature
% 1000) / 100);
1134 } else { /* !cpufreq_verbose && !bootverbose */
1135 device_printf(sc
->dev
,
1136 "ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
1137 HZ2MHZ(arm_freq
), HZ2MHZ(core_freq
), HZ2MHZ(sdram_freq
),
1138 (sc
->turbo_mode
== BCM2835_FIRMWARE_TURBO_ON
) ? "ON":"OFF");
1141 /* keep in softc (MHz/mV) */
1142 sc
->arm_max_freq
= HZ2MHZ(arm_max_freq
);
1143 sc
->arm_min_freq
= HZ2MHZ(arm_min_freq
);
1144 sc
->core_max_freq
= HZ2MHZ(core_max_freq
);
1145 sc
->core_min_freq
= HZ2MHZ(core_min_freq
);
1146 sc
->sdram_max_freq
= HZ2MHZ(sdram_max_freq
);
1147 sc
->sdram_min_freq
= HZ2MHZ(sdram_min_freq
);
1148 sc
->max_voltage_core
= OFFSET2MVOLT(max_voltage_core
);
1149 sc
->min_voltage_core
= OFFSET2MVOLT(min_voltage_core
);
1151 /* if turbo is on, set to max values */
1152 if (sc
->turbo_mode
== BCM2835_FIRMWARE_TURBO_ON
) {
1153 bcm2835_cpufreq_set_clock_rate(sc
,
1154 BCM2835_FIRMWARE_CLOCK_ID_ARM
, arm_max_freq
);
1155 DELAY(TRANSITION_LATENCY
);
1156 bcm2835_cpufreq_set_clock_rate(sc
,
1157 BCM2835_FIRMWARE_CLOCK_ID_CORE
, core_max_freq
);
1158 DELAY(TRANSITION_LATENCY
);
1159 bcm2835_cpufreq_set_clock_rate(sc
,
1160 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
, sdram_max_freq
);
1161 DELAY(TRANSITION_LATENCY
);
1163 bcm2835_cpufreq_set_clock_rate(sc
,
1164 BCM2835_FIRMWARE_CLOCK_ID_ARM
, arm_min_freq
);
1165 DELAY(TRANSITION_LATENCY
);
1166 bcm2835_cpufreq_set_clock_rate(sc
,
1167 BCM2835_FIRMWARE_CLOCK_ID_CORE
, core_min_freq
);
1168 DELAY(TRANSITION_LATENCY
);
1169 bcm2835_cpufreq_set_clock_rate(sc
,
1170 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
, sdram_min_freq
);
1171 DELAY(TRANSITION_LATENCY
);
1176 /* add human readable temperature to dev.cpu node */
1177 cpu
= device_get_parent(sc
->dev
);
1179 ctx
= device_get_sysctl_ctx(cpu
);
1180 SYSCTL_ADD_PROC(ctx
,
1181 SYSCTL_CHILDREN(device_get_sysctl_tree(cpu
)), OID_AUTO
,
1183 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_NEEDGIANT
, sc
, 0,
1184 sysctl_bcm2835_devcpu_temperature
, "IK",
1185 "Current SoC temperature");
1188 /* release this hook (continue boot) */
1189 config_intrhook_disestablish(&sc
->init_hook
);
1193 bcm2835_cpufreq_identify(driver_t
*driver
, device_t parent
)
1195 const struct ofw_compat_data
*compat
;
1198 root
= OF_finddevice("/");
1199 for (compat
= compat_data
; compat
->ocd_str
!= NULL
; compat
++)
1200 if (ofw_bus_node_is_compatible(root
, compat
->ocd_str
))
1203 if (compat
->ocd_data
== 0)
1206 DPRINTF("driver=%p, parent=%p\n", driver
, parent
);
1207 if (device_find_child(parent
, "bcm2835_cpufreq", -1) != NULL
)
1209 if (BUS_ADD_CHILD(parent
, 0, "bcm2835_cpufreq", -1) == NULL
)
1210 device_printf(parent
, "add child failed\n");
1214 bcm2835_cpufreq_probe(device_t dev
)
1217 if (device_get_unit(dev
) != 0)
1219 device_set_desc(dev
, "CPU Frequency Control");
1225 bcm2835_cpufreq_attach(device_t dev
)
1227 struct bcm2835_cpufreq_softc
*sc
;
1228 struct sysctl_oid
*oid
;
1231 sc
= device_get_softc(dev
);
1233 sc
->firmware
= devclass_get_device(
1234 devclass_find("bcm2835_firmware"), 0);
1235 if (sc
->firmware
== NULL
) {
1236 device_printf(dev
, "Unable to find firmware device\n");
1240 /* initial values */
1241 sc
->arm_max_freq
= -1;
1242 sc
->arm_min_freq
= -1;
1243 sc
->core_max_freq
= -1;
1244 sc
->core_min_freq
= -1;
1245 sc
->sdram_max_freq
= -1;
1246 sc
->sdram_min_freq
= -1;
1247 sc
->max_voltage_core
= 0;
1248 sc
->min_voltage_core
= 0;
1250 /* setup sysctl at first device */
1251 if (device_get_unit(dev
) == 0) {
1252 sysctl_ctx_init(&bcm2835_sysctl_ctx
);
1253 /* create node for hw.cpufreq */
1254 oid
= SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx
,
1255 SYSCTL_STATIC_CHILDREN(_hw
), OID_AUTO
, "cpufreq",
1256 CTLFLAG_RD
| CTLFLAG_MPSAFE
, NULL
, "");
1258 /* Frequency (Hz) */
1259 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1260 OID_AUTO
, "arm_freq",
1261 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_NEEDGIANT
, sc
, 0,
1262 sysctl_bcm2835_cpufreq_arm_freq
, "IU",
1263 "ARM frequency (Hz)");
1264 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1265 OID_AUTO
, "core_freq",
1266 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_NEEDGIANT
, sc
, 0,
1267 sysctl_bcm2835_cpufreq_core_freq
, "IU",
1268 "Core frequency (Hz)");
1269 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1270 OID_AUTO
, "sdram_freq",
1271 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_NEEDGIANT
, sc
, 0,
1272 sysctl_bcm2835_cpufreq_sdram_freq
, "IU",
1273 "SDRAM frequency (Hz)");
1276 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1278 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_NEEDGIANT
, sc
, 0,
1279 sysctl_bcm2835_cpufreq_turbo
, "IU",
1280 "Disables dynamic clocking");
1282 /* Voltage (offset from 1.2V in units of 0.025V) */
1283 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1284 OID_AUTO
, "voltage_core",
1285 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_NEEDGIANT
, sc
, 0,
1286 sysctl_bcm2835_cpufreq_voltage_core
, "I",
1287 "ARM/GPU core voltage"
1288 "(offset from 1.2V in units of 0.025V)");
1289 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1290 OID_AUTO
, "voltage_sdram",
1291 CTLTYPE_INT
| CTLFLAG_WR
| CTLFLAG_NEEDGIANT
, sc
,
1292 0, sysctl_bcm2835_cpufreq_voltage_sdram
, "I",
1293 "SDRAM voltage (offset from 1.2V in units of 0.025V)");
1295 /* Voltage individual SDRAM */
1296 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1297 OID_AUTO
, "voltage_sdram_c",
1298 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_NEEDGIANT
, sc
,
1299 0, sysctl_bcm2835_cpufreq_voltage_sdram_c
, "I",
1300 "SDRAM controller voltage"
1301 "(offset from 1.2V in units of 0.025V)");
1302 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1303 OID_AUTO
, "voltage_sdram_i",
1304 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_NEEDGIANT
, sc
,
1305 0, sysctl_bcm2835_cpufreq_voltage_sdram_i
, "I",
1306 "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)");
1307 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1308 OID_AUTO
, "voltage_sdram_p",
1309 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_NEEDGIANT
, sc
,
1310 0, sysctl_bcm2835_cpufreq_voltage_sdram_p
, "I",
1311 "SDRAM phy voltage (offset from 1.2V in units of 0.025V)");
1314 SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx
, SYSCTL_CHILDREN(oid
),
1315 OID_AUTO
, "temperature",
1316 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_NEEDGIANT
, sc
, 0,
1317 sysctl_bcm2835_cpufreq_temperature
, "I",
1318 "SoC temperature (thousandths of a degree C)");
1322 sema_init(&vc_sema
, 1, "vcsema");
1324 /* register callback for using mbox when interrupts are enabled */
1325 sc
->init_hook
.ich_func
= bcm2835_cpufreq_init
;
1326 sc
->init_hook
.ich_arg
= sc
;
1328 if (config_intrhook_establish(&sc
->init_hook
) != 0) {
1329 device_printf(dev
, "config_intrhook_establish failed\n");
1333 /* this device is controlled by cpufreq(4) */
1334 cpufreq_register(dev
);
1340 bcm2835_cpufreq_detach(device_t dev
)
1343 sema_destroy(&vc_sema
);
1345 return (cpufreq_unregister(dev
));
1349 bcm2835_cpufreq_set(device_t dev
, const struct cf_setting
*cf
)
1351 struct bcm2835_cpufreq_softc
*sc
;
1352 uint32_t rate_hz
, rem
;
1353 int resp_freq
, arm_freq
, min_freq
, core_freq
;
1358 if (cf
== NULL
|| cf
->freq
< 0)
1361 sc
= device_get_softc(dev
);
1363 /* setting clock (Hz) */
1364 rate_hz
= (uint32_t)MHZ2HZ(cf
->freq
);
1365 rem
= rate_hz
% HZSTEP
;
1370 /* adjust min freq */
1371 min_freq
= sc
->arm_min_freq
;
1372 if (sc
->turbo_mode
!= BCM2835_FIRMWARE_TURBO_ON
)
1373 if (min_freq
> cpufreq_lowest_freq
)
1374 min_freq
= cpufreq_lowest_freq
;
1376 if (rate_hz
< MHZ2HZ(min_freq
) || rate_hz
> MHZ2HZ(sc
->arm_max_freq
))
1379 /* set new value and verify it */
1382 cur_freq
= bcm2835_cpufreq_get_clock_rate(sc
,
1383 BCM2835_FIRMWARE_CLOCK_ID_ARM
);
1385 resp_freq
= bcm2835_cpufreq_set_clock_rate(sc
,
1386 BCM2835_FIRMWARE_CLOCK_ID_ARM
, rate_hz
);
1387 DELAY(TRANSITION_LATENCY
);
1388 arm_freq
= bcm2835_cpufreq_get_clock_rate(sc
,
1389 BCM2835_FIRMWARE_CLOCK_ID_ARM
);
1392 * if non-turbo and lower than or equal min_freq,
1393 * clock down core and sdram to default first.
1395 if (sc
->turbo_mode
!= BCM2835_FIRMWARE_TURBO_ON
) {
1396 core_freq
= bcm2835_cpufreq_get_clock_rate(sc
,
1397 BCM2835_FIRMWARE_CLOCK_ID_CORE
);
1398 if (rate_hz
> MHZ2HZ(sc
->arm_min_freq
)) {
1399 bcm2835_cpufreq_set_clock_rate(sc
,
1400 BCM2835_FIRMWARE_CLOCK_ID_CORE
,
1401 MHZ2HZ(sc
->core_max_freq
));
1402 DELAY(TRANSITION_LATENCY
);
1403 bcm2835_cpufreq_set_clock_rate(sc
,
1404 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
,
1405 MHZ2HZ(sc
->sdram_max_freq
));
1406 DELAY(TRANSITION_LATENCY
);
1408 if (sc
->core_min_freq
< DEFAULT_CORE_FREQUENCY
&&
1409 core_freq
> DEFAULT_CORE_FREQUENCY
) {
1410 /* first, down to 250, then down to min */
1411 DELAY(TRANSITION_LATENCY
);
1412 bcm2835_cpufreq_set_clock_rate(sc
,
1413 BCM2835_FIRMWARE_CLOCK_ID_CORE
,
1414 MHZ2HZ(DEFAULT_CORE_FREQUENCY
));
1415 DELAY(TRANSITION_LATENCY
);
1416 /* reset core voltage */
1417 bcm2835_cpufreq_set_voltage(sc
,
1418 BCM2835_FIRMWARE_VOLTAGE_ID_CORE
, 0);
1419 DELAY(TRANSITION_LATENCY
);
1421 bcm2835_cpufreq_set_clock_rate(sc
,
1422 BCM2835_FIRMWARE_CLOCK_ID_CORE
,
1423 MHZ2HZ(sc
->core_min_freq
));
1424 DELAY(TRANSITION_LATENCY
);
1425 bcm2835_cpufreq_set_clock_rate(sc
,
1426 BCM2835_FIRMWARE_CLOCK_ID_SDRAM
,
1427 MHZ2HZ(sc
->sdram_min_freq
));
1428 DELAY(TRANSITION_LATENCY
);
1434 if (resp_freq
< 0 || arm_freq
< 0 || resp_freq
!= arm_freq
) {
1435 device_printf(dev
, "wrong freq\n");
1438 DPRINTF("cpufreq: %d -> %d\n", cur_freq
, arm_freq
);
1444 bcm2835_cpufreq_get(device_t dev
, struct cf_setting
*cf
)
1446 struct bcm2835_cpufreq_softc
*sc
;
1452 sc
= device_get_softc(dev
);
1453 memset(cf
, CPUFREQ_VAL_UNKNOWN
, sizeof(*cf
));
1456 /* get cuurent value */
1458 arm_freq
= bcm2835_cpufreq_get_clock_rate(sc
,
1459 BCM2835_FIRMWARE_CLOCK_ID_ARM
);
1462 device_printf(dev
, "can't get clock\n");
1466 /* CPU clock in MHz or 100ths of a percent. */
1467 cf
->freq
= HZ2MHZ(arm_freq
);
1468 /* Voltage in mV. */
1469 cf
->volts
= CPUFREQ_VAL_UNKNOWN
;
1470 /* Power consumed in mW. */
1471 cf
->power
= CPUFREQ_VAL_UNKNOWN
;
1472 /* Transition latency in us. */
1473 cf
->lat
= TRANSITION_LATENCY
;
1474 /* Driver providing this setting. */
1481 bcm2835_cpufreq_make_freq_list(device_t dev
, struct cf_setting
*sets
,
1484 struct bcm2835_cpufreq_softc
*sc
;
1485 int freq
, min_freq
, volts
, rem
;
1488 sc
= device_get_softc(dev
);
1489 freq
= sc
->arm_max_freq
;
1490 min_freq
= sc
->arm_min_freq
;
1492 /* adjust head freq to STEP */
1493 rem
= freq
% MHZSTEP
;
1495 if (freq
< min_freq
)
1498 /* if non-turbo, add extra low freq */
1499 if (sc
->turbo_mode
!= BCM2835_FIRMWARE_TURBO_ON
)
1500 if (min_freq
> cpufreq_lowest_freq
)
1501 min_freq
= cpufreq_lowest_freq
;
1503 /* XXX RPi2 have only 900/600MHz */
1505 volts
= sc
->min_voltage_core
;
1506 sets
[idx
].freq
= freq
;
1507 sets
[idx
].volts
= volts
;
1508 sets
[idx
].lat
= TRANSITION_LATENCY
;
1509 sets
[idx
].dev
= dev
;
1511 if (freq
!= min_freq
) {
1512 sets
[idx
].freq
= min_freq
;
1513 sets
[idx
].volts
= volts
;
1514 sets
[idx
].lat
= TRANSITION_LATENCY
;
1515 sets
[idx
].dev
= dev
;
1524 bcm2835_cpufreq_settings(device_t dev
, struct cf_setting
*sets
, int *count
)
1526 struct bcm2835_cpufreq_softc
*sc
;
1528 if (sets
== NULL
|| count
== NULL
)
1531 sc
= device_get_softc(dev
);
1532 if (sc
->arm_min_freq
< 0 || sc
->arm_max_freq
< 0) {
1533 printf("device is not configured\n");
1537 /* fill data with unknown value */
1538 memset(sets
, CPUFREQ_VAL_UNKNOWN
, sizeof(*sets
) * (*count
));
1539 /* create new array up to count */
1540 bcm2835_cpufreq_make_freq_list(dev
, sets
, count
);
1546 bcm2835_cpufreq_type(device_t dev
, int *type
)
1551 *type
= CPUFREQ_TYPE_ABSOLUTE
;
1556 static device_method_t bcm2835_cpufreq_methods
[] = {
1557 /* Device interface */
1558 DEVMETHOD(device_identify
, bcm2835_cpufreq_identify
),
1559 DEVMETHOD(device_probe
, bcm2835_cpufreq_probe
),
1560 DEVMETHOD(device_attach
, bcm2835_cpufreq_attach
),
1561 DEVMETHOD(device_detach
, bcm2835_cpufreq_detach
),
1563 /* cpufreq interface */
1564 DEVMETHOD(cpufreq_drv_set
, bcm2835_cpufreq_set
),
1565 DEVMETHOD(cpufreq_drv_get
, bcm2835_cpufreq_get
),
1566 DEVMETHOD(cpufreq_drv_settings
, bcm2835_cpufreq_settings
),
1567 DEVMETHOD(cpufreq_drv_type
, bcm2835_cpufreq_type
),
1572 static driver_t bcm2835_cpufreq_driver
= {
1574 bcm2835_cpufreq_methods
,
1575 sizeof(struct bcm2835_cpufreq_softc
),
1578 DRIVER_MODULE(bcm2835_cpufreq
, cpu
, bcm2835_cpufreq_driver
, 0, 0);
1579 MODULE_DEPEND(bcm2835_cpufreq
, bcm2835_firmware
, 1, 1, 1);