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