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