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