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