1use core::cell::Cell;
6use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
7use kernel::utilities::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
8use kernel::utilities::StaticRef;
9
10register_structs! {
11 GpioClockRegisters {
12 (0x000 => ctrl: ReadWrite<u32, CLK_GPOUTx_CTRL::Register>),
14 (0x004 => div: ReadWrite<u32, CLK_GPOUTx_DIV::Register>),
16 (0x008 => selected: ReadOnly<u32, CLK_GPOUTx_SELECTED::Register>),
18 (0x00C => @END),
20 },
21 ClocksRegisters {
22 (0x000 => clk_gpio: [GpioClockRegisters; 4]),
23 (0x030 => clk_ref_ctrl: ReadWrite<u32, CLK_REF_CTRL::Register>),
25 (0x034 => clk_ref_div: ReadWrite<u32>),
27 (0x038 => clk_ref_selected: ReadOnly<u32, CLK_REF_SELECTED::Register>),
29 (0x03C => clk_sys_ctrl: ReadWrite<u32, CLK_SYS_CTRL::Register>),
31 (0x040 => clk_sys_div: ReadWrite<u32, CLK_SYS_DIV::Register>),
33 (0x044 => clk_sys_selected: ReadOnly<u32, CLK_SYS_SELECTED::Register>),
35 (0x048 => clk_peri_ctrl: ReadWrite<u32, CLK_PERI_CTRL::Register>),
37 (0x04C => _reserved0),
38 (0x050 => clk_peri_selected: ReadOnly<u32, CLK_PERI_SELECTED::Register>),
40 (0x054 => clk_usb_ctrl: ReadWrite<u32, CLK_USB_CTRL::Register>),
42 (0x058 => clk_usb_div: ReadWrite<u32>),
44 (0x05C => clk_usb_selected: ReadOnly<u32, CLK_USB_SELECTED::Register>),
46 (0x060 => clk_adc_ctrl: ReadWrite<u32, CLK_ADC_CTRL::Register>),
48 (0x064 => clk_adc_div: ReadWrite<u32>),
50 (0x068 => clk_adc_selected: ReadOnly<u32, CLK_ADC_SELECTED::Register>),
52 (0x06C => clk_rtc_ctrl: ReadWrite<u32, CLK_RTC_CTRL::Register>),
54 (0x070 => clk_rtc_div: ReadWrite<u32, CLK_RTC_DIV::Register>),
56 (0x074 => clk_rtc_selected: ReadOnly<u32, CLK_RTC_SELECTED::Register>),
58
59 (0x078 => clk_sys_resus_ctrl: ReadWrite<u32, CLK_SYS_RESUS_CTRL::Register>),
60
61 (0x07C => clk_sys_resus_status: ReadWrite<u32>),
62 (0x080 => fc0_ref_khz: ReadWrite<u32>),
64 (0x084 => fc0_min_khz: ReadWrite<u32>),
66 (0x088 => fc0_max_khz: ReadWrite<u32>),
68 (0x08C => fc0_delay: ReadWrite<u32>),
71 (0x090 => fc0_interval: ReadWrite<u32>),
74 (0x094 => fc0_src: ReadWrite<u32>),
77 (0x098 => fc0_status: ReadWrite<u32, FC0_STATUS::Register>),
79 (0x09C => fc0_result: ReadWrite<u32, FC0_RESULT::Register>),
81 (0x0A0 => wake_en0: ReadWrite<u32, WAKE_EN0::Register>),
83 (0x0A4 => wake_en1: ReadWrite<u32, WAKE_EN1::Register>),
85 (0x0A8 => sleep_en0: ReadWrite<u32, SLEEP_EN0::Register>),
87 (0x0AC => sleep_en1: ReadWrite<u32, SLEEP_EN1::Register>),
89 (0x0B0 => enabled0: ReadWrite<u32, ENABLED0::Register>),
91 (0x0B4 => enabled1: ReadWrite<u32, ENABLED1::Register>),
93 (0x0B8 => intr: ReadWrite<u32>),
95 (0x0BC => inte: ReadWrite<u32>),
97 (0x0C0 => intf: ReadWrite<u32>),
99 (0x0C4 => ints: ReadWrite<u32>),
101 (0x0C8 => @END),
102 },
103 PllRegisters {
104 (0x000 => cs: ReadWrite<u32, CS::Register>),
110 (0x004 => pwr: ReadWrite<u32, PWR::Register>),
112 (0x008 => fbdiv_int: ReadWrite<u32, FBDIV_INT::Register>),
115 (0x00C => prim: ReadWrite<u32, PRIM::Register>),
119 (0x010 => @END),
120 }
121}
122
123register_bitfields![u32,
124 CLK_GPOUTx_CTRL [
125 NUDGE OFFSET(20) NUMBITS(1) [],
128 PHASE OFFSET(16) NUMBITS(2) [],
131 DC50 OFFSET(12) NUMBITS(1) [],
133 ENABLE OFFSET(11) NUMBITS(1) [],
135 KILL OFFSET(10) NUMBITS(1) [],
137 AUXSRC OFFSET(5) NUMBITS(4) [
139 CLKSRC_PLL_SYS = 0,
140 CLKSRC_GPIN0 = 1,
141 CLKSRC_GPIN1 = 2,
142 CLKSRC_PLL_USB = 3,
143 ROSC_CLKSRC = 4,
144 XOSC_CLKSRC = 5,
145 CLK_SYS = 6,
146 CLK_USB = 7,
147 CLK_ADC = 8,
148 CLK_RTC = 9,
149 CLK_REF = 0xa
150 ]
151 ],
152 CLK_GPOUTx_DIV [
153 INT OFFSET(8) NUMBITS(24) [],
155 FRAC OFFSET(0) NUMBITS(8) []
157 ],
158 CLK_GPOUTx_SELECTED [
159 VALUE OFFSET (0) NUMBITS (32) []
160 ],
161 CLK_REF_CTRL [
162 AUXSRC OFFSET(5) NUMBITS(2) [
164
165 CLKSRC_PLL_USB = 0x0,
166 CLKSRC_GPIN0 = 0x1,
167 CLKSRC_GPIN1 = 0x2
168 ],
169 SRC OFFSET(0) NUMBITS(2) [
171
172 ROSC_CLKSRC_PH = 0x0,
173 CLKSRC_CLK_REF_AUX = 0x1,
174 XOSC_CLKSRC = 0x2
175 ]
176 ],
177 CLK_REF_DIV [
178 INT OFFSET(8) NUMBITS(2) []
180 ],
181 CLK_REF_SELECTED [
182 VALUE OFFSET (0) NUMBITS (32) []
183 ],
184 CLK_SYS_CTRL [
185 AUXSRC OFFSET(5) NUMBITS(3) [
187
188 CLKSRC_PLL_SYS = 0x0,
189 CLKSRC_PLL_USB = 0x1,
190 ROSC_CLKSRC = 0x2,
191 XOSC_CLKSRC = 0x3,
192 CLKSRC_GPIN0 = 0x4,
193 CLKSRC_GPIN1 = 0x5
194 ],
195 SRC OFFSET(0) NUMBITS(1) [
197 CLKSRC_CLK_SYS_AUX = 1,
198 CLK_REF = 0,
199 ]
200 ],
201 CLK_SYS_DIV [
202 INT OFFSET(8) NUMBITS(24) [],
204 FRAC OFFSET(0) NUMBITS(8) []
206 ],
207 CLK_SYS_SELECTED [
208 VALUE OFFSET (0) NUMBITS (32) []
209 ],
210 CLK_PERI_CTRL [
211 ENABLE OFFSET(11) NUMBITS(1) [],
213 KILL OFFSET(10) NUMBITS(1) [],
215 AUXSRC OFFSET(5) NUMBITS(3) [
217 CLK_SYS = 0,
218 CLKSRC_PLL_SYS = 1,
219 CLKSRC_PLL_USB = 2,
220 ROSC_CLKSRC_PH = 3,
221 XOSC_CLKSRC = 4,
222 CLKSRC_GPIN0 = 5,
223 CLKSRC_GPIN1 = 6
224 ]
225 ],
226 CLK_PERI_SELECTED [
227 VALUE OFFSET (0) NUMBITS (32) []
228 ],
229 CLK_USB_CTRL [
230 NUDGE OFFSET(20) NUMBITS(1) [],
233 PHASE OFFSET(16) NUMBITS(2) [],
236 ENABLE OFFSET(11) NUMBITS(1) [],
238 KILL OFFSET(10) NUMBITS(1) [],
240 AUXSRC OFFSET(5) NUMBITS(3) [
242
243 CLKSRC_PLL_USB = 0,
244 CLKSRC_PLL_SYS = 1,
245 ROSC_CLKSRC_PH = 2,
246 XOSC_CLKSRC = 3,
247 CLKSRC_GPIN0 = 4,
248 CLKSRC_GPIN1 = 5
249 ]
250 ],
251 CLK_USB_DIV [
252 INT OFFSET(8) NUMBITS(2) []
254 ],
255 CLK_USB_SELECTED [
256 VALUE OFFSET (0) NUMBITS (32) []
257 ],
258 CLK_ADC_CTRL [
259 NUDGE OFFSET(20) NUMBITS(1) [],
262 PHASE OFFSET(16) NUMBITS(2) [],
265 ENABLE OFFSET(11) NUMBITS(1) [],
267 KILL OFFSET(10) NUMBITS(1) [],
269 AUXSRC OFFSET(5) NUMBITS(3) [
271
272 CLKSRC_PLL_USB = 0,
273 CLKSRC_PLL_SYS = 1,
274 ROSC_CLKSRC_PH = 2,
275 XOSC_CLKSRC = 3,
276 CLKSRC_GPIN0 = 4,
277 CLKSRC_GPIN1 = 5
278 ]
279 ],
280 CLK_ADC_DIV [
281 INT OFFSET(8) NUMBITS(2) []
283 ],
284 CLK_ADC_SELECTED [
285 VALUE OFFSET (0) NUMBITS (32) []
286 ],
287 CLK_RTC_CTRL [
288 NUDGE OFFSET(20) NUMBITS(1) [],
291 PHASE OFFSET(16) NUMBITS(2) [],
294 ENABLE OFFSET(11) NUMBITS(1) [],
296 KILL OFFSET(10) NUMBITS(1) [],
298 AUXSRC OFFSET(5) NUMBITS(3) [
300
301 CLKSRC_PLL_USB = 0,
302 CLKSRC_PLL_SYS = 1,
303 ROSC_CLKSRC_PH = 2,
304 XOSC_CLKSRC = 3,
305 CLKSRC_GPIN0 = 4,
306 CLKSRC_GPIN1 = 5
307 ]
308 ],
309 CLK_RTC_DIV [
310 INT OFFSET(8) NUMBITS(24) [],
312 FRAC OFFSET(0) NUMBITS(8) []
314 ],
315 CLK_RTC_SELECTED [
316 VALUE OFFSET (0) NUMBITS (32) []
317 ],
318 CLK_SYS_RESUS_CTRL [
319 CLEAR OFFSET(16) NUMBITS(1) [],
321 FRCE OFFSET(12) NUMBITS(1) [],
323 ENABLE OFFSET(8) NUMBITS(1) [],
325 TIMEOUT OFFSET(0) NUMBITS(8) []
328 ],
329 CLK_SYS_RESUS_STATUS [
330 RESUSSED OFFSET(0) NUMBITS(1) []
332 ],
333 FC0_REF_KHZ [
334
335 FC0_REF_KHZ OFFSET(0) NUMBITS(20) []
336 ],
337 FC0_MIN_KHZ [
338
339 FC0_MIN_KHZ OFFSET(0) NUMBITS(25) []
340 ],
341 FC0_MAX_KHZ [
342
343 FC0_MAX_KHZ OFFSET(0) NUMBITS(25) []
344 ],
345 FC0_DELAY [
346
347 FC0_DELAY OFFSET(0) NUMBITS(3) []
348 ],
349 FC0_INTERVAL [
350
351 FC0_INTERVAL OFFSET(0) NUMBITS(4) []
352 ],
353 FC0_SRC [
354
355 FC0_SRC OFFSET(0) NUMBITS(8) [
356
357 NULL = 0
358 ]
359 ],
360 FC0_STATUS [
361 DIED OFFSET(28) NUMBITS(1) [],
363 FAST OFFSET(24) NUMBITS(1) [],
365 SLOW OFFSET(20) NUMBITS(1) [],
367 FAIL OFFSET(16) NUMBITS(1) [],
369 WAITING OFFSET(12) NUMBITS(1) [],
371 RUNNING OFFSET(8) NUMBITS(1) [],
373 DONE OFFSET(4) NUMBITS(1) [],
375 PASS OFFSET(0) NUMBITS(1) []
377 ],
378 FC0_RESULT [
379
380 KHZ OFFSET(5) NUMBITS(25) [],
381
382 FRAC OFFSET(0) NUMBITS(5) []
383 ],
384 WAKE_EN0 [
385
386 clk_sys_sram3 OFFSET(31) NUMBITS(1) [],
387
388 clk_sys_sram2 OFFSET(30) NUMBITS(1) [],
389
390 clk_sys_sram1 OFFSET(29) NUMBITS(1) [],
391
392 clk_sys_sram0 OFFSET(28) NUMBITS(1) [],
393
394 clk_sys_spi1 OFFSET(27) NUMBITS(1) [],
395
396 clk_peri_spi1 OFFSET(26) NUMBITS(1) [],
397
398 clk_sys_spi0 OFFSET(25) NUMBITS(1) [],
399
400 clk_peri_spi0 OFFSET(24) NUMBITS(1) [],
401
402 clk_sys_sio OFFSET(23) NUMBITS(1) [],
403
404 clk_sys_rtc OFFSET(22) NUMBITS(1) [],
405
406 clk_rtc_rtc OFFSET(21) NUMBITS(1) [],
407
408 clk_sys_rosc OFFSET(20) NUMBITS(1) [],
409
410 clk_sys_rom OFFSET(19) NUMBITS(1) [],
411
412 clk_sys_resets OFFSET(18) NUMBITS(1) [],
413
414 clk_sys_pwm OFFSET(17) NUMBITS(1) [],
415
416 clk_sys_psm OFFSET(16) NUMBITS(1) [],
417
418 clk_sys_pll_usb OFFSET(15) NUMBITS(1) [],
419
420 clk_sys_pll_sys OFFSET(14) NUMBITS(1) [],
421
422 clk_sys_pio1 OFFSET(13) NUMBITS(1) [],
423
424 clk_sys_pio0 OFFSET(12) NUMBITS(1) [],
425
426 clk_sys_pads OFFSET(11) NUMBITS(1) [],
427
428 clk_sys_vreg_and_chip_reset OFFSET(10) NUMBITS(1) [],
429
430 clk_sys_jtag OFFSET(9) NUMBITS(1) [],
431
432 clk_sys_io OFFSET(8) NUMBITS(1) [],
433
434 clk_sys_i2c1 OFFSET(7) NUMBITS(1) [],
435
436 clk_sys_i2c0 OFFSET(6) NUMBITS(1) [],
437
438 clk_sys_dma OFFSET(5) NUMBITS(1) [],
439
440 clk_sys_busfabric OFFSET(4) NUMBITS(1) [],
441
442 clk_sys_busctrl OFFSET(3) NUMBITS(1) [],
443
444 clk_sys_adc OFFSET(2) NUMBITS(1) [],
445
446 clk_adc_adc OFFSET(1) NUMBITS(1) [],
447
448 clk_sys_clocks OFFSET(0) NUMBITS(1) []
449 ],
450 WAKE_EN1 [
451
452 clk_sys_xosc OFFSET(14) NUMBITS(1) [],
453
454 clk_sys_xip OFFSET(13) NUMBITS(1) [],
455
456 clk_sys_watchdog OFFSET(12) NUMBITS(1) [],
457
458 clk_usb_usbctrl OFFSET(11) NUMBITS(1) [],
459
460 clk_sys_usbctrl OFFSET(10) NUMBITS(1) [],
461
462 clk_sys_uart1 OFFSET(9) NUMBITS(1) [],
463
464 clk_peri_uart1 OFFSET(8) NUMBITS(1) [],
465
466 clk_sys_uart0 OFFSET(7) NUMBITS(1) [],
467
468 clk_peri_uart0 OFFSET(6) NUMBITS(1) [],
469
470 clk_sys_timer OFFSET(5) NUMBITS(1) [],
471
472 clk_sys_tbman OFFSET(4) NUMBITS(1) [],
473
474 clk_sys_sysinfo OFFSET(3) NUMBITS(1) [],
475
476 clk_sys_syscfg OFFSET(2) NUMBITS(1) [],
477
478 clk_sys_sram5 OFFSET(1) NUMBITS(1) [],
479
480 clk_sys_sram4 OFFSET(0) NUMBITS(1) []
481 ],
482 SLEEP_EN0 [
483
484 clk_sys_sram3 OFFSET(31) NUMBITS(1) [],
485
486 clk_sys_sram2 OFFSET(30) NUMBITS(1) [],
487
488 clk_sys_sram1 OFFSET(29) NUMBITS(1) [],
489
490 clk_sys_sram0 OFFSET(28) NUMBITS(1) [],
491
492 clk_sys_spi1 OFFSET(27) NUMBITS(1) [],
493
494 clk_peri_spi1 OFFSET(26) NUMBITS(1) [],
495
496 clk_sys_spi0 OFFSET(25) NUMBITS(1) [],
497
498 clk_peri_spi0 OFFSET(24) NUMBITS(1) [],
499
500 clk_sys_sio OFFSET(23) NUMBITS(1) [],
501
502 clk_sys_rtc OFFSET(22) NUMBITS(1) [],
503
504 clk_rtc_rtc OFFSET(21) NUMBITS(1) [],
505
506 clk_sys_rosc OFFSET(20) NUMBITS(1) [],
507
508 clk_sys_rom OFFSET(19) NUMBITS(1) [],
509
510 clk_sys_resets OFFSET(18) NUMBITS(1) [],
511
512 clk_sys_pwm OFFSET(17) NUMBITS(1) [],
513
514 clk_sys_psm OFFSET(16) NUMBITS(1) [],
515
516 clk_sys_pll_usb OFFSET(15) NUMBITS(1) [],
517
518 clk_sys_pll_sys OFFSET(14) NUMBITS(1) [],
519
520 clk_sys_pio1 OFFSET(13) NUMBITS(1) [],
521
522 clk_sys_pio0 OFFSET(12) NUMBITS(1) [],
523
524 clk_sys_pads OFFSET(11) NUMBITS(1) [],
525
526 clk_sys_vreg_and_chip_reset OFFSET(10) NUMBITS(1) [],
527
528 clk_sys_jtag OFFSET(9) NUMBITS(1) [],
529
530 clk_sys_io OFFSET(8) NUMBITS(1) [],
531
532 clk_sys_i2c1 OFFSET(7) NUMBITS(1) [],
533
534 clk_sys_i2c0 OFFSET(6) NUMBITS(1) [],
535
536 clk_sys_dma OFFSET(5) NUMBITS(1) [],
537
538 clk_sys_busfabric OFFSET(4) NUMBITS(1) [],
539
540 clk_sys_busctrl OFFSET(3) NUMBITS(1) [],
541
542 clk_sys_adc OFFSET(2) NUMBITS(1) [],
543
544 clk_adc_adc OFFSET(1) NUMBITS(1) [],
545
546 clk_sys_clocks OFFSET(0) NUMBITS(1) []
547 ],
548 SLEEP_EN1 [
549
550 clk_sys_xosc OFFSET(14) NUMBITS(1) [],
551
552 clk_sys_xip OFFSET(13) NUMBITS(1) [],
553
554 clk_sys_watchdog OFFSET(12) NUMBITS(1) [],
555
556 clk_usb_usbctrl OFFSET(11) NUMBITS(1) [],
557
558 clk_sys_usbctrl OFFSET(10) NUMBITS(1) [],
559
560 clk_sys_uart1 OFFSET(9) NUMBITS(1) [],
561
562 clk_peri_uart1 OFFSET(8) NUMBITS(1) [],
563
564 clk_sys_uart0 OFFSET(7) NUMBITS(1) [],
565
566 clk_peri_uart0 OFFSET(6) NUMBITS(1) [],
567
568 clk_sys_timer OFFSET(5) NUMBITS(1) [],
569
570 clk_sys_tbman OFFSET(4) NUMBITS(1) [],
571
572 clk_sys_sysinfo OFFSET(3) NUMBITS(1) [],
573
574 clk_sys_syscfg OFFSET(2) NUMBITS(1) [],
575
576 clk_sys_sram5 OFFSET(1) NUMBITS(1) [],
577
578 clk_sys_sram4 OFFSET(0) NUMBITS(1) []
579 ],
580 ENABLED0 [
581
582 clk_sys_sram3 OFFSET(31) NUMBITS(1) [],
583
584 clk_sys_sram2 OFFSET(30) NUMBITS(1) [],
585
586 clk_sys_sram1 OFFSET(29) NUMBITS(1) [],
587
588 clk_sys_sram0 OFFSET(28) NUMBITS(1) [],
589
590 clk_sys_spi1 OFFSET(27) NUMBITS(1) [],
591
592 clk_peri_spi1 OFFSET(26) NUMBITS(1) [],
593
594 clk_sys_spi0 OFFSET(25) NUMBITS(1) [],
595
596 clk_peri_spi0 OFFSET(24) NUMBITS(1) [],
597
598 clk_sys_sio OFFSET(23) NUMBITS(1) [],
599
600 clk_sys_rtc OFFSET(22) NUMBITS(1) [],
601
602 clk_rtc_rtc OFFSET(21) NUMBITS(1) [],
603
604 clk_sys_rosc OFFSET(20) NUMBITS(1) [],
605
606 clk_sys_rom OFFSET(19) NUMBITS(1) [],
607
608 clk_sys_resets OFFSET(18) NUMBITS(1) [],
609
610 clk_sys_pwm OFFSET(17) NUMBITS(1) [],
611
612 clk_sys_psm OFFSET(16) NUMBITS(1) [],
613
614 clk_sys_pll_usb OFFSET(15) NUMBITS(1) [],
615
616 clk_sys_pll_sys OFFSET(14) NUMBITS(1) [],
617
618 clk_sys_pio1 OFFSET(13) NUMBITS(1) [],
619
620 clk_sys_pio0 OFFSET(12) NUMBITS(1) [],
621
622 clk_sys_pads OFFSET(11) NUMBITS(1) [],
623
624 clk_sys_vreg_and_chip_reset OFFSET(10) NUMBITS(1) [],
625
626 clk_sys_jtag OFFSET(9) NUMBITS(1) [],
627
628 clk_sys_io OFFSET(8) NUMBITS(1) [],
629
630 clk_sys_i2c1 OFFSET(7) NUMBITS(1) [],
631
632 clk_sys_i2c0 OFFSET(6) NUMBITS(1) [],
633
634 clk_sys_dma OFFSET(5) NUMBITS(1) [],
635
636 clk_sys_busfabric OFFSET(4) NUMBITS(1) [],
637
638 clk_sys_busctrl OFFSET(3) NUMBITS(1) [],
639
640 clk_sys_adc OFFSET(2) NUMBITS(1) [],
641
642 clk_adc_adc OFFSET(1) NUMBITS(1) [],
643
644 clk_sys_clocks OFFSET(0) NUMBITS(1) []
645 ],
646 ENABLED1 [
647
648 clk_sys_xosc OFFSET(14) NUMBITS(1) [],
649
650 clk_sys_xip OFFSET(13) NUMBITS(1) [],
651
652 clk_sys_watchdog OFFSET(12) NUMBITS(1) [],
653
654 clk_usb_usbctrl OFFSET(11) NUMBITS(1) [],
655
656 clk_sys_usbctrl OFFSET(10) NUMBITS(1) [],
657
658 clk_sys_uart1 OFFSET(9) NUMBITS(1) [],
659
660 clk_peri_uart1 OFFSET(8) NUMBITS(1) [],
661
662 clk_sys_uart0 OFFSET(7) NUMBITS(1) [],
663
664 clk_peri_uart0 OFFSET(6) NUMBITS(1) [],
665
666 clk_sys_timer OFFSET(5) NUMBITS(1) [],
667
668 clk_sys_tbman OFFSET(4) NUMBITS(1) [],
669
670 clk_sys_sysinfo OFFSET(3) NUMBITS(1) [],
671
672 clk_sys_syscfg OFFSET(2) NUMBITS(1) [],
673
674 clk_sys_sram5 OFFSET(1) NUMBITS(1) [],
675
676 clk_sys_sram4 OFFSET(0) NUMBITS(1) []
677 ],
678 INTR [
679
680 CLK_SYS_RESUS OFFSET(0) NUMBITS(1) []
681 ],
682 INTE [
683
684 CLK_SYS_RESUS OFFSET(0) NUMBITS(1) []
685 ],
686 INTF [
687
688 CLK_SYS_RESUS OFFSET(0) NUMBITS(1) []
689 ],
690 INTS [
691
692 CLK_SYS_RESUS OFFSET(0) NUMBITS(1) []
693 ]
694];
695
696register_bitfields![u32,
697 CS [
698 LOCK OFFSET(31) NUMBITS(1) [],
700 BYPASS OFFSET(8) NUMBITS(1) [],
702 REFDIV OFFSET(0) NUMBITS(6) []
706 ],
707 PWR [
708 VCOPD OFFSET(5) NUMBITS(1) [],
711 POSTDIVPD OFFSET(3) NUMBITS(1) [],
714 DSMPD OFFSET(2) NUMBITS(1) [],
717 PD OFFSET(0) NUMBITS(1) []
720 ],
721 FBDIV_INT [
722 FBDIV_INT OFFSET(0) NUMBITS(12) []
724 ],
725 PRIM [
726 POSTDIV1 OFFSET(16) NUMBITS(3) [],
728 POSTDIV2 OFFSET(12) NUMBITS(3) []
730 ]
731];
732
733const PLL_SYS_BASE: StaticRef<PllRegisters> =
734 unsafe { StaticRef::new(0x40028000 as *const PllRegisters) };
735
736const PLL_USB_BASE: StaticRef<PllRegisters> =
737 unsafe { StaticRef::new(0x4002C000 as *const PllRegisters) };
738
739const CLOCKS_BASE: StaticRef<ClocksRegisters> =
740 unsafe { StaticRef::new(0x40008000 as *const ClocksRegisters) };
741
742const NUM_CLOCKS: usize = 10;
743
744pub struct Clocks {
745 registers: StaticRef<ClocksRegisters>,
746 pll_registers: &'static [StaticRef<PllRegisters>],
747 frequencies: [Cell<u32>; NUM_CLOCKS],
748}
749
750pub enum PllClock {
751 Sys = 0,
752 Usb = 1,
753}
754
755#[derive(Copy, Clone, PartialEq, Debug)]
756#[repr(usize)]
757pub enum Clock {
758 GpioOut0 = 0,
759 GpioOut1 = 1,
760 GpioOut2 = 2,
761 GpioOut3 = 3,
762 Reference = 4,
763 System = 5,
764 Peripheral = 6,
765 Usb = 7,
766 Adc = 8,
767 Rtc = 9,
768}
769
770#[derive(Copy, Clone, PartialEq, Debug)]
771#[repr(u8)]
772pub enum GpioAuxiliaryClockSource {
773 PllSys = 0,
774 Gpio0 = 1,
775 Gpio1 = 2,
776 PllUsb = 3,
777 Rsoc = 4,
778 Xosc = 5,
779 Sys = 6,
780 Usb = 7,
781 Adc = 8,
782 Rtc = 9,
783 Ref = 10,
784}
785
786#[derive(Copy, Clone, PartialEq, Debug)]
787#[repr(u8)]
788pub enum ReferenceClockSource {
789 Rsoc = 0,
790 Auxiliary = 1,
791 Xosc = 2,
792}
793
794#[derive(Copy, Clone, PartialEq, Debug)]
795#[repr(u8)]
796pub enum ReferenceAuxiliaryClockSource {
797 PllUsb = 0,
798 Gpio0 = 1,
799 Gpio1 = 2,
800}
801
802#[derive(Copy, Clone, PartialEq, Debug)]
803#[repr(u8)]
804pub enum SystemClockSource {
805 Reference = 0,
806 Auxiliary = 1,
807}
808
809#[derive(Copy, Clone, PartialEq, Debug)]
810#[repr(u8)]
811pub enum SystemAuxiliaryClockSource {
812 PllSys = 0,
813 PllUsb = 1,
814 Rsoc = 2,
815 Xsoc = 3,
816 Gpio0 = 4,
817 Gpio1 = 5,
818}
819
820#[derive(Copy, Clone, PartialEq, Debug)]
821#[repr(u8)]
822pub enum PeripheralAuxiliaryClockSource {
823 System = 0,
824 PllSys = 1,
825 PllUsb = 2,
826 Rsoc = 3,
827 Xsoc = 4,
828 Gpio0 = 5,
829 Gpio1 = 6,
830}
831
832#[derive(Copy, Clone, PartialEq, Debug)]
833#[repr(u8)]
834pub enum UsbAuxiliaryClockSource {
835 PllSys = 0,
836 PllUsb = 1,
837 Rsoc = 2,
838 Xsoc = 3,
839 Gpio0 = 4,
840 Gpio1 = 5,
841}
842
843#[derive(Copy, Clone, PartialEq, Debug)]
844#[repr(u8)]
845pub enum AdcAuxiliaryClockSource {
846 PllSys = 0,
847 PllUsb = 1,
848 Rsoc = 2,
849 Xsoc = 3,
850 Gpio0 = 4,
851 Gpio1 = 5,
852}
853
854#[derive(Copy, Clone, PartialEq, Debug)]
855#[repr(u8)]
856pub enum RtcAuxiliaryClockSource {
857 PllSys = 0,
858 PllUsb = 1,
859 Rsoc = 2,
860 Xsoc = 3,
861 Gpio0 = 4,
862 Gpio1 = 5,
863}
864
865#[derive(Copy, Clone, PartialEq, Debug)]
866pub enum ClockSource {
867 GpioOut,
868 Reference(ReferenceClockSource),
869 System(SystemClockSource),
870 Peripheral,
871 Usb,
872 Adc,
873 Rtc,
874}
875
876#[derive(Copy, Clone, PartialEq, Debug)]
877pub enum ClockAuxiliarySource {
878 GpioOut(GpioAuxiliaryClockSource),
879 Reference(ReferenceAuxiliaryClockSource),
880 System(SystemAuxiliaryClockSource),
881 Peripheral(PeripheralAuxiliaryClockSource),
882 Usb(UsbAuxiliaryClockSource),
883 Adc(AdcAuxiliaryClockSource),
884 Rtc(RtcAuxiliaryClockSource),
885}
886
887impl Clocks {
888 pub const fn new() -> Self {
889 Self {
890 registers: CLOCKS_BASE,
891 pll_registers: &[PLL_SYS_BASE, PLL_USB_BASE],
892 frequencies: [
893 Cell::new(0),
894 Cell::new(0),
895 Cell::new(0),
896 Cell::new(0),
897 Cell::new(0),
898 Cell::new(0),
899 Cell::new(0),
900 Cell::new(0),
901 Cell::new(0),
902 Cell::new(0),
903 ],
904 }
905 }
906
907 pub fn enable_resus(&self) {
908 self.registers
909 .clk_sys_resus_ctrl
910 .modify(CLK_SYS_RESUS_CTRL::ENABLE::SET);
911 }
912
913 pub fn disable_resus(&self) {
914 self.registers
915 .clk_sys_resus_ctrl
916 .modify(CLK_SYS_RESUS_CTRL::ENABLE::CLEAR);
917 }
918
919 pub fn disable_sys_aux(&self) {
920 self.registers
921 .clk_sys_ctrl
922 .modify(CLK_SYS_CTRL::SRC::CLK_REF);
923 while self
924 .registers
925 .clk_sys_selected
926 .read(CLK_SYS_SELECTED::VALUE)
927 != 0x1
928 {}
929 }
930
931 pub fn disable_ref_aux(&self) {
932 self.registers
933 .clk_ref_ctrl
934 .modify(CLK_REF_CTRL::SRC::ROSC_CLKSRC_PH);
935 while self
936 .registers
937 .clk_ref_selected
938 .read(CLK_REF_SELECTED::VALUE)
939 != 0x1
940 {}
941 }
942
943 pub fn pll_init(
944 &self,
945 clock: PllClock,
946 xosc_freq: u32,
947 refdiv: u32,
948 vco_freq: u32,
949 post_div1: u32,
950 post_div2: u32,
951 ) {
952 let registers = self.pll_registers[clock as usize];
953
954 registers
956 .pwr
957 .modify(PWR::PD::SET + PWR::DSMPD::SET + PWR::POSTDIVPD::SET + PWR::VCOPD::SET);
958 registers.fbdiv_int.modify(FBDIV_INT::FBDIV_INT.val(0));
959
960 let ref_mhz = xosc_freq / refdiv;
961 registers.cs.modify(CS::REFDIV.val(refdiv));
962
963 let fbdiv = vco_freq / (ref_mhz * 1000000);
965
966 if fbdiv < 16 || fbdiv > 320 {
968 panic!("Invalid feedback divider number {} not in [16, 320]", fbdiv)
969 }
970
971 if post_div1 < 1 || post_div1 > 7 || post_div2 < 1 || post_div2 > 7 {
972 panic!(
973 "Invalid post_div number {} or {} not in [1, 7]",
974 post_div1, post_div2
975 );
976 }
977
978 if post_div2 > post_div1 {
979 panic!(
980 "post_div2 must be less than post_div1 ({} >= {})",
981 post_div1, post_div2
982 );
983 }
984
985 if ref_mhz > vco_freq / 16 {
986 panic!(
987 "ref_mhz must be less than vco_freq / 16 ({} <= {})",
988 ref_mhz,
989 vco_freq / 16
990 );
991 }
992
993 registers.fbdiv_int.modify(FBDIV_INT::FBDIV_INT.val(fbdiv));
995
996 registers.pwr.modify(PWR::PD::CLEAR + PWR::VCOPD::CLEAR);
998
999 while !registers.cs.is_set(CS::LOCK) {}
1001
1002 registers
1004 .prim
1005 .modify(PRIM::POSTDIV1.val(post_div1) + PRIM::POSTDIV2.val(post_div2));
1006
1007 registers.pwr.modify(PWR::POSTDIVPD::CLEAR);
1009 }
1010
1011 pub fn pll_deinit(&self, clock: PllClock) {
1012 self.pll_registers[clock as usize]
1013 .pwr
1014 .modify(PWR::PD::SET + PWR::DSMPD::SET + PWR::POSTDIVPD::SET + PWR::VCOPD::SET);
1015 }
1016
1017 pub fn set_frequency(&self, clock: Clock, freq: u32) {
1018 self.frequencies[clock as usize].set(freq);
1019 }
1020
1021 pub fn get_frequency(&self, clock: Clock) -> u32 {
1022 self.frequencies[clock as usize].get()
1023 }
1024
1025 fn set_divider(&self, clock: Clock, div: u32) {
1026 match clock {
1027 Clock::GpioOut0 | Clock::GpioOut1 | Clock::GpioOut2 | Clock::GpioOut3 => {
1028 self.registers.clk_gpio[clock as usize].div.set(div)
1029 }
1030 Clock::System => self.registers.clk_sys_div.set(div),
1031 Clock::Reference => self.registers.clk_ref_div.set(div),
1032 Clock::Usb => self.registers.clk_usb_div.set(div),
1033 Clock::Adc => self.registers.clk_adc_div.set(div),
1034 Clock::Rtc => self.registers.clk_rtc_div.set(div),
1035 _ => panic!("failed to set div"),
1037 }
1038 }
1039
1040 fn get_divider(&self, source_freq: u32, freq: u32) -> u32 {
1041 (((source_freq as u64) << 8) / freq as u64) as u32
1043 }
1044
1045 #[cfg(any(doc, all(target_arch = "arm", target_os = "none")))]
1046 #[inline]
1047 fn loop_3_cycles(&self, clock: Clock) {
1048 if self.get_frequency(clock) > 0 {
1049 let _delay_cyc: u32 = self.get_frequency(Clock::System) / self.get_frequency(clock) + 1;
1050 unsafe {
1051 use core::arch::asm;
1052 asm! (
1053 "1:",
1054 "subs {0}, #1",
1055 "bne 1b",
1056 in (reg) _delay_cyc
1057 );
1058 }
1059 }
1060 }
1061
1062 #[cfg(not(any(doc, all(target_arch = "arm", target_os = "none"))))]
1063 fn loop_3_cycles(&self, _clock: Clock) {
1064 unimplemented!()
1065 }
1066
1067 pub fn configure_gpio_out(
1068 &self,
1069 clock: Clock,
1070 auxiliary_source: GpioAuxiliaryClockSource,
1071 source_freq: u32,
1072 freq: u32,
1073 ) {
1074 match clock {
1075 Clock::GpioOut0 | Clock::GpioOut1 | Clock::GpioOut2 | Clock::GpioOut3 => {
1076 if freq > source_freq {
1077 panic!(
1078 "freq is greater than source freq ({} > {})",
1079 freq, source_freq
1080 );
1081 }
1082
1083 let div = self.get_divider(source_freq, freq);
1084
1085 if div > self.registers.clk_gpio[clock as usize].div.get() {
1090 self.set_divider(clock, div);
1091 }
1092
1093 self.registers.clk_gpio[clock as usize]
1094 .ctrl
1095 .modify(CLK_GPOUTx_CTRL::ENABLE::CLEAR);
1096 self.loop_3_cycles(clock);
1101
1102 self.registers.clk_gpio[clock as usize]
1103 .ctrl
1104 .modify(CLK_GPOUTx_CTRL::AUXSRC.val(auxiliary_source as u32));
1105
1106 self.registers.clk_gpio[clock as usize]
1107 .ctrl
1108 .modify(CLK_GPOUTx_CTRL::ENABLE::SET);
1109
1110 self.set_divider(clock, div);
1114
1115 self.set_frequency(clock, freq);
1116 }
1117 _ => panic!("trying to set a non gpio clock"),
1118 }
1119 }
1120
1121 pub fn configure_system(
1122 &self,
1123 source: SystemClockSource,
1124 auxiliary_source: SystemAuxiliaryClockSource,
1125 source_freq: u32,
1126 freq: u32,
1127 ) {
1128 if freq > source_freq {
1129 panic!(
1130 "freq is greater than source freq ({} > {})",
1131 freq, source_freq
1132 );
1133 }
1134 let div = self.get_divider(source_freq, freq);
1135
1136 if div > self.registers.clk_sys_div.get() {
1141 self.set_divider(Clock::System, div);
1142 }
1143
1144 if source == SystemClockSource::Auxiliary {
1149 self.registers
1150 .clk_sys_ctrl
1151 .modify(CLK_SYS_CTRL::SRC::CLK_REF);
1152 while self
1153 .registers
1154 .clk_sys_selected
1155 .read(CLK_SYS_SELECTED::VALUE)
1156 != 0x1
1157 {}
1158 }
1159
1160 self.registers
1161 .clk_sys_ctrl
1162 .modify(CLK_SYS_CTRL::AUXSRC.val(auxiliary_source as u32));
1163 self.registers
1164 .clk_sys_ctrl
1165 .modify(CLK_SYS_CTRL::SRC.val(source as u32));
1166 while self
1167 .registers
1168 .clk_sys_selected
1169 .read(CLK_SYS_SELECTED::VALUE)
1170 & (1 << (source as u32))
1171 == 0x0
1172 {}
1173
1174 self.set_divider(Clock::System, div);
1178
1179 self.set_frequency(Clock::System, freq);
1180 }
1181
1182 pub fn configure_reference(
1183 &self,
1184 source: ReferenceClockSource,
1185 auxiliary_source: ReferenceAuxiliaryClockSource,
1186 source_freq: u32,
1187 freq: u32,
1188 ) {
1189 if freq > source_freq {
1190 panic!(
1191 "freq is greater than source freq ({} > {})",
1192 freq, source_freq
1193 );
1194 }
1195 let div = self.get_divider(source_freq, freq);
1196
1197 if div > self.registers.clk_ref_div.get() {
1202 self.set_divider(Clock::Reference, div);
1203 }
1204
1205 if source == ReferenceClockSource::Auxiliary {
1210 self.registers
1211 .clk_ref_ctrl
1212 .modify(CLK_REF_CTRL::SRC::ROSC_CLKSRC_PH);
1213 while self
1214 .registers
1215 .clk_ref_selected
1216 .read(CLK_REF_SELECTED::VALUE)
1217 != 0x1
1218 {}
1219 }
1220
1221 self.registers
1222 .clk_ref_ctrl
1223 .modify(CLK_REF_CTRL::AUXSRC.val(auxiliary_source as u32));
1224 self.registers
1225 .clk_ref_ctrl
1226 .modify(CLK_REF_CTRL::SRC.val(source as u32));
1227 while self
1228 .registers
1229 .clk_ref_selected
1230 .read(CLK_REF_SELECTED::VALUE)
1231 & (1 << (source as u32))
1232 == 0x0
1233 {}
1234
1235 self.set_divider(Clock::Reference, div);
1239
1240 self.set_frequency(Clock::Reference, freq);
1241 }
1242
1243 pub fn configure_peripheral(
1244 &self,
1245 auxiliary_source: PeripheralAuxiliaryClockSource,
1246 freq: u32,
1247 ) {
1248 self.registers
1249 .clk_peri_ctrl
1250 .modify(CLK_PERI_CTRL::ENABLE::CLEAR);
1251
1252 self.loop_3_cycles(Clock::Peripheral);
1257
1258 self.registers
1259 .clk_peri_ctrl
1260 .modify(CLK_PERI_CTRL::AUXSRC.val(auxiliary_source as u32));
1261
1262 self.registers
1263 .clk_peri_ctrl
1264 .modify(CLK_PERI_CTRL::ENABLE::SET);
1265
1266 self.set_frequency(Clock::Peripheral, freq);
1267 }
1268
1269 pub fn configure_usb(
1270 &self,
1271 auxiliary_source: UsbAuxiliaryClockSource,
1272 source_freq: u32,
1273 freq: u32,
1274 ) {
1275 if freq > source_freq {
1276 panic!(
1277 "freq is greater than source freq ({} > {})",
1278 freq, source_freq
1279 );
1280 }
1281 let div = self.get_divider(source_freq, freq);
1282
1283 if div > self.registers.clk_usb_div.get() {
1288 self.set_divider(Clock::Usb, div);
1289 }
1290
1291 self.registers
1292 .clk_usb_ctrl
1293 .modify(CLK_USB_CTRL::ENABLE::CLEAR);
1294 self.loop_3_cycles(Clock::Usb);
1299
1300 self.registers
1301 .clk_usb_ctrl
1302 .modify(CLK_USB_CTRL::AUXSRC.val(auxiliary_source as u32));
1303
1304 self.registers
1305 .clk_usb_ctrl
1306 .modify(CLK_USB_CTRL::ENABLE::SET);
1307
1308 self.set_divider(Clock::Usb, div);
1312
1313 self.set_frequency(Clock::Usb, freq);
1314 }
1315
1316 pub fn configure_adc(
1317 &self,
1318 auxiliary_source: AdcAuxiliaryClockSource,
1319 source_freq: u32,
1320 freq: u32,
1321 ) {
1322 if freq > source_freq {
1323 panic!(
1324 "freq is greater than source freq ({} > {})",
1325 freq, source_freq
1326 );
1327 }
1328 let div = self.get_divider(source_freq, freq);
1329
1330 if div > self.registers.clk_adc_div.get() {
1335 self.set_divider(Clock::Adc, div);
1336 }
1337
1338 self.registers
1339 .clk_adc_ctrl
1340 .modify(CLK_ADC_CTRL::ENABLE::CLEAR);
1341 self.loop_3_cycles(Clock::Adc);
1346
1347 self.registers
1348 .clk_adc_ctrl
1349 .modify(CLK_ADC_CTRL::AUXSRC.val(auxiliary_source as u32));
1350
1351 self.registers
1352 .clk_adc_ctrl
1353 .modify(CLK_ADC_CTRL::ENABLE::SET);
1354
1355 self.set_divider(Clock::Adc, div);
1359
1360 self.set_frequency(Clock::Adc, freq);
1361 }
1362
1363 pub fn configure_rtc(
1364 &self,
1365 auxiliary_source: RtcAuxiliaryClockSource,
1366 source_freq: u32,
1367 freq: u32,
1368 ) {
1369 if freq > source_freq {
1370 panic!(
1371 "freq is greater than source freq ({} > {})",
1372 freq, source_freq
1373 );
1374 }
1375 let div = self.get_divider(source_freq, freq);
1376
1377 if div > self.registers.clk_rtc_div.get() {
1382 self.set_divider(Clock::Rtc, div);
1383 }
1384
1385 self.registers
1386 .clk_rtc_ctrl
1387 .modify(CLK_RTC_CTRL::ENABLE::CLEAR);
1388 self.loop_3_cycles(Clock::Rtc);
1393
1394 self.registers
1395 .clk_rtc_ctrl
1396 .modify(CLK_RTC_CTRL::AUXSRC.val(auxiliary_source as u32));
1397
1398 self.registers
1399 .clk_rtc_ctrl
1400 .modify(CLK_RTC_CTRL::ENABLE::SET);
1401
1402 self.set_divider(Clock::Rtc, div);
1406
1407 self.set_frequency(Clock::Rtc, freq);
1408 }
1409}