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