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