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