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