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 */
93static struct sema vc_sema;
94
95static struct sysctl_ctx_list bcm2835_sysctl_ctx;
96
97struct 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
121static 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
132static int cpufreq_verbose = 0;
133TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose);
134static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ;
135TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq);
136
137#ifdef PROP_DEBUG
138static void
139bcm2835_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
156static int
157bcm2835_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
197static int
198bcm2835_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
238static int
239bcm2835_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
279static int
280bcm2835_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
347static int
348bcm2835_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
386static int
387bcm2835_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
432static int
433bcm2835_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
472static int
473bcm2835_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}
511static int
512bcm2835_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
551static int
552bcm2835_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
603static int
604bcm2835_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
642static int
643sysctl_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
674static int
675sysctl_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
708static int
709sysctl_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
741static int
742sysctl_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
777static int
778sysctl_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
813static int
814sysctl_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
851static int
852sysctl_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
888static int
889sysctl_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
925static int
926sysctl_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
973static int
974sysctl_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
995static int
996sysctl_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
1020static void
1021bcm2835_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
1199static void
1200bcm2835_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
1220static int
1221bcm2835_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
1231static int
1232bcm2835_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
1346static int
1347bcm2835_cpufreq_detach(device_t dev)
1348{
1349
1350	sema_destroy(&vc_sema);
1351
1352	return (cpufreq_unregister(dev));
1353}
1354
1355static int
1356bcm2835_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
1450static int
1451bcm2835_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
1487static int
1488bcm2835_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
1545static int
1546bcm2835_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
1567static int
1568bcm2835_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
1578static 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
1594static driver_t bcm2835_cpufreq_driver = {
1595	"bcm2835_cpufreq",
1596	bcm2835_cpufreq_methods,
1597	sizeof(struct bcm2835_cpufreq_softc),
1598};
1599
1600DRIVER_MODULE(bcm2835_cpufreq, cpu, bcm2835_cpufreq_driver, 0, 0);
1601MODULE_DEPEND(bcm2835_cpufreq, bcm2835_firmware, 1, 1, 1);
1602