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