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 "
10541:
1055 subs {0}, #1
1056 bne 1b
1057 ",
1058 in (reg) _delay_cyc,
1059 );
1060 }
1061 }
1062 }
1063
1064 #[cfg(not(any(doc, all(target_arch = "arm", target_os = "none"))))]
1065 fn loop_3_cycles(&self, _clock: Clock) {
1066 unimplemented!()
1067 }
1068
1069 pub fn configure_gpio_out(
1070 &self,
1071 clock: Clock,
1072 auxiliary_source: GpioAuxiliaryClockSource,
1073 source_freq: u32,
1074 freq: u32,
1075 ) {
1076 match clock {
1077 Clock::GpioOut0 | Clock::GpioOut1 | Clock::GpioOut2 | Clock::GpioOut3 => {
1078 if freq > source_freq {
1079 panic!(
1080 "freq is greater than source freq ({} > {})",
1081 freq, source_freq
1082 );
1083 }
1084
1085 let div = self.get_divider(source_freq, freq);
1086
1087 if div > self.registers.clk_gpio[clock as usize].div.get() {
1092 self.set_divider(clock, div);
1093 }
1094
1095 self.registers.clk_gpio[clock as usize]
1096 .ctrl
1097 .modify(CLK_GPOUTx_CTRL::ENABLE::CLEAR);
1098 self.loop_3_cycles(clock);
1103
1104 self.registers.clk_gpio[clock as usize]
1105 .ctrl
1106 .modify(CLK_GPOUTx_CTRL::AUXSRC.val(auxiliary_source as u32));
1107
1108 self.registers.clk_gpio[clock as usize]
1109 .ctrl
1110 .modify(CLK_GPOUTx_CTRL::ENABLE::SET);
1111
1112 self.set_divider(clock, div);
1116
1117 self.set_frequency(clock, freq);
1118 }
1119 _ => panic!("trying to set a non gpio clock"),
1120 }
1121 }
1122
1123 pub fn configure_system(
1124 &self,
1125 source: SystemClockSource,
1126 auxiliary_source: SystemAuxiliaryClockSource,
1127 source_freq: u32,
1128 freq: u32,
1129 ) {
1130 if freq > source_freq {
1131 panic!(
1132 "freq is greater than source freq ({} > {})",
1133 freq, source_freq
1134 );
1135 }
1136 let div = self.get_divider(source_freq, freq);
1137
1138 if div > self.registers.clk_sys_div.get() {
1143 self.set_divider(Clock::System, div);
1144 }
1145
1146 if source == SystemClockSource::Auxiliary {
1151 self.registers
1152 .clk_sys_ctrl
1153 .modify(CLK_SYS_CTRL::SRC::CLK_REF);
1154 while self
1155 .registers
1156 .clk_sys_selected
1157 .read(CLK_SYS_SELECTED::VALUE)
1158 != 0x1
1159 {}
1160 }
1161
1162 self.registers
1163 .clk_sys_ctrl
1164 .modify(CLK_SYS_CTRL::AUXSRC.val(auxiliary_source as u32));
1165 self.registers
1166 .clk_sys_ctrl
1167 .modify(CLK_SYS_CTRL::SRC.val(source as u32));
1168 while self
1169 .registers
1170 .clk_sys_selected
1171 .read(CLK_SYS_SELECTED::VALUE)
1172 & (1 << (source as u32))
1173 == 0x0
1174 {}
1175
1176 self.set_divider(Clock::System, div);
1180
1181 self.set_frequency(Clock::System, freq);
1182 }
1183
1184 pub fn configure_reference(
1185 &self,
1186 source: ReferenceClockSource,
1187 auxiliary_source: ReferenceAuxiliaryClockSource,
1188 source_freq: u32,
1189 freq: u32,
1190 ) {
1191 if freq > source_freq {
1192 panic!(
1193 "freq is greater than source freq ({} > {})",
1194 freq, source_freq
1195 );
1196 }
1197 let div = self.get_divider(source_freq, freq);
1198
1199 if div > self.registers.clk_ref_div.get() {
1204 self.set_divider(Clock::Reference, div);
1205 }
1206
1207 if source == ReferenceClockSource::Auxiliary {
1212 self.registers
1213 .clk_ref_ctrl
1214 .modify(CLK_REF_CTRL::SRC::ROSC_CLKSRC_PH);
1215 while self
1216 .registers
1217 .clk_ref_selected
1218 .read(CLK_REF_SELECTED::VALUE)
1219 != 0x1
1220 {}
1221 }
1222
1223 self.registers
1224 .clk_ref_ctrl
1225 .modify(CLK_REF_CTRL::AUXSRC.val(auxiliary_source as u32));
1226 self.registers
1227 .clk_ref_ctrl
1228 .modify(CLK_REF_CTRL::SRC.val(source as u32));
1229 while self
1230 .registers
1231 .clk_ref_selected
1232 .read(CLK_REF_SELECTED::VALUE)
1233 & (1 << (source as u32))
1234 == 0x0
1235 {}
1236
1237 self.set_divider(Clock::Reference, div);
1241
1242 self.set_frequency(Clock::Reference, freq);
1243 }
1244
1245 pub fn configure_peripheral(
1246 &self,
1247 auxiliary_source: PeripheralAuxiliaryClockSource,
1248 freq: u32,
1249 ) {
1250 self.registers
1251 .clk_peri_ctrl
1252 .modify(CLK_PERI_CTRL::ENABLE::CLEAR);
1253
1254 self.loop_3_cycles(Clock::Peripheral);
1259
1260 self.registers
1261 .clk_peri_ctrl
1262 .modify(CLK_PERI_CTRL::AUXSRC.val(auxiliary_source as u32));
1263
1264 self.registers
1265 .clk_peri_ctrl
1266 .modify(CLK_PERI_CTRL::ENABLE::SET);
1267
1268 self.set_frequency(Clock::Peripheral, freq);
1269 }
1270
1271 pub fn configure_usb(
1272 &self,
1273 auxiliary_source: UsbAuxiliaryClockSource,
1274 source_freq: u32,
1275 freq: u32,
1276 ) {
1277 if freq > source_freq {
1278 panic!(
1279 "freq is greater than source freq ({} > {})",
1280 freq, source_freq
1281 );
1282 }
1283 let div = self.get_divider(source_freq, freq);
1284
1285 if div > self.registers.clk_usb_div.get() {
1290 self.set_divider(Clock::Usb, div);
1291 }
1292
1293 self.registers
1294 .clk_usb_ctrl
1295 .modify(CLK_USB_CTRL::ENABLE::CLEAR);
1296 self.loop_3_cycles(Clock::Usb);
1301
1302 self.registers
1303 .clk_usb_ctrl
1304 .modify(CLK_USB_CTRL::AUXSRC.val(auxiliary_source as u32));
1305
1306 self.registers
1307 .clk_usb_ctrl
1308 .modify(CLK_USB_CTRL::ENABLE::SET);
1309
1310 self.set_divider(Clock::Usb, div);
1314
1315 self.set_frequency(Clock::Usb, freq);
1316 }
1317
1318 pub fn configure_adc(
1319 &self,
1320 auxiliary_source: AdcAuxiliaryClockSource,
1321 source_freq: u32,
1322 freq: u32,
1323 ) {
1324 if freq > source_freq {
1325 panic!(
1326 "freq is greater than source freq ({} > {})",
1327 freq, source_freq
1328 );
1329 }
1330 let div = self.get_divider(source_freq, freq);
1331
1332 if div > self.registers.clk_adc_div.get() {
1337 self.set_divider(Clock::Adc, div);
1338 }
1339
1340 self.registers
1341 .clk_adc_ctrl
1342 .modify(CLK_ADC_CTRL::ENABLE::CLEAR);
1343 self.loop_3_cycles(Clock::Adc);
1348
1349 self.registers
1350 .clk_adc_ctrl
1351 .modify(CLK_ADC_CTRL::AUXSRC.val(auxiliary_source as u32));
1352
1353 self.registers
1354 .clk_adc_ctrl
1355 .modify(CLK_ADC_CTRL::ENABLE::SET);
1356
1357 self.set_divider(Clock::Adc, div);
1361
1362 self.set_frequency(Clock::Adc, freq);
1363 }
1364
1365 pub fn configure_rtc(
1366 &self,
1367 auxiliary_source: RtcAuxiliaryClockSource,
1368 source_freq: u32,
1369 freq: u32,
1370 ) {
1371 if freq > source_freq {
1372 panic!(
1373 "freq is greater than source freq ({} > {})",
1374 freq, source_freq
1375 );
1376 }
1377 let div = self.get_divider(source_freq, freq);
1378
1379 if div > self.registers.clk_rtc_div.get() {
1384 self.set_divider(Clock::Rtc, div);
1385 }
1386
1387 self.registers
1388 .clk_rtc_ctrl
1389 .modify(CLK_RTC_CTRL::ENABLE::CLEAR);
1390 self.loop_3_cycles(Clock::Rtc);
1395
1396 self.registers
1397 .clk_rtc_ctrl
1398 .modify(CLK_RTC_CTRL::AUXSRC.val(auxiliary_source as u32));
1399
1400 self.registers
1401 .clk_rtc_ctrl
1402 .modify(CLK_RTC_CTRL::ENABLE::SET);
1403
1404 self.set_divider(Clock::Rtc, div);
1408
1409 self.set_frequency(Clock::Rtc, freq);
1410 }
1411}