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