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