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