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