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