xref: /freebsd/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c (revision fcb560670601b2a4d87bb31d7531c8dcc37ee71b)
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);
1818