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