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