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