aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1021/drivers/fsl_clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1021/drivers/fsl_clock.c')
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1021/drivers/fsl_clock.c1223
1 files changed, 1223 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1021/drivers/fsl_clock.c b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1021/drivers/fsl_clock.c
new file mode 100644
index 000000000..beae64276
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1021/drivers/fsl_clock.c
@@ -0,0 +1,1223 @@
1/*
2 * Copyright 2018 - 2020 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include "fsl_clock.h"
9/* Component ID definition, used by tools. */
10#ifndef FSL_COMPONENT_ID
11#define FSL_COMPONENT_ID "platform.drivers.clock"
12#endif
13
14/*******************************************************************************
15 * Definitions
16 ******************************************************************************/
17/* To make full use of CM7 hardware FPU, use double instead of uint64_t in clock driver to
18achieve better performance, it is depend on the IDE Floating point settings, if double precision is selected
19in IDE, clock_64b_t will switch to double type automatically. only support IAR and MDK here */
20#if __FPU_USED
21
22#if (defined(__ICCARM__))
23
24#if (__ARMVFP__ >= __ARMFPV5__) && \
25 (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/
26typedef double clock_64b_t;
27#else
28typedef uint64_t clock_64b_t;
29#endif
30
31#elif (defined(__GNUC__))
32
33#if (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/
34typedef double clock_64b_t;
35#else
36typedef uint64_t clock_64b_t;
37#endif
38
39#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
40
41#if defined __TARGET_FPU_FPV5_D16
42typedef double clock_64b_t;
43#else
44typedef uint64_t clock_64b_t;
45#endif
46
47#else
48typedef uint64_t clock_64b_t;
49#endif
50
51#else
52typedef uint64_t clock_64b_t;
53#endif
54
55/*******************************************************************************
56 * Variables
57 ******************************************************************************/
58
59/* External XTAL (OSC) clock frequency. */
60volatile uint32_t g_xtalFreq;
61/* External RTC XTAL clock frequency. */
62volatile uint32_t g_rtcXtalFreq;
63
64/*******************************************************************************
65 * Prototypes
66 ******************************************************************************/
67
68/*!
69 * @brief Get the periph clock frequency.
70 *
71 * @return Periph clock frequency in Hz.
72 */
73static uint32_t CLOCK_GetPeriphClkFreq(void);
74
75/*!
76 * @brief Get the frequency of PLL USB1 software clock.
77 *
78 * @return The frequency of PLL USB1 software clock.
79 */
80static uint32_t CLOCK_GetPllUsb1SWFreq(void);
81
82/*******************************************************************************
83 * Code
84 ******************************************************************************/
85
86static uint32_t CLOCK_GetPeriphClkFreq(void)
87{
88 uint32_t freq;
89
90 /* Periph_clk2_clk ---> Periph_clk */
91 if ((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK_SEL_MASK) != 0UL)
92 {
93 switch (CCM->CBCMR & CCM_CBCMR_PERIPH_CLK2_SEL_MASK)
94 {
95 /* Pll3_sw_clk ---> Periph_clk2_clk ---> Periph_clk */
96 case CCM_CBCMR_PERIPH_CLK2_SEL(0U):
97 freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
98 break;
99
100 /* Osc_clk ---> Periph_clk2_clk ---> Periph_clk */
101 case CCM_CBCMR_PERIPH_CLK2_SEL(1U):
102 freq = CLOCK_GetOscFreq();
103 break;
104
105 case CCM_CBCMR_PERIPH_CLK2_SEL(2U):
106 freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
107 break;
108
109 case CCM_CBCMR_PERIPH_CLK2_SEL(3U):
110 default:
111 freq = 0U;
112 break;
113 }
114
115 freq /= (((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >> CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) + 1U);
116 }
117 /* Pre_Periph_clk ---> Periph_clk */
118 else
119 {
120 switch (CCM->CBCMR & CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
121 {
122 /* PLL2 */
123 case CCM_CBCMR_PRE_PERIPH_CLK_SEL(0U):
124 freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
125 break;
126
127 /* PLL3 PFD3 */
128 case CCM_CBCMR_PRE_PERIPH_CLK_SEL(1U):
129 freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd3);
130 break;
131
132 /* PLL2 PFD3 */
133 case CCM_CBCMR_PRE_PERIPH_CLK_SEL(2U):
134 freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd3);
135 break;
136
137 /* PLL6 divided(/1) */
138 case CCM_CBCMR_PRE_PERIPH_CLK_SEL(3U):
139 freq = 500000000U;
140 break;
141
142 default:
143 freq = 0U;
144 break;
145 }
146 }
147
148 return freq;
149}
150
151static uint32_t CLOCK_GetPllUsb1SWFreq(void)
152{
153 uint32_t freq;
154
155 switch ((CCM->CCSR & CCM_CCSR_PLL3_SW_CLK_SEL_MASK) >> CCM_CCSR_PLL3_SW_CLK_SEL_SHIFT)
156 {
157 case 0:
158 {
159 freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
160 break;
161 }
162 case 1:
163 {
164 freq = 24000000UL;
165 break;
166 }
167 default:
168 freq = 0UL;
169 break;
170 }
171
172 return freq;
173}
174/*!
175 * brief Initialize the external 24MHz clock.
176 *
177 * This function supports two modes:
178 * 1. Use external crystal oscillator.
179 * 2. Bypass the external crystal oscillator, using input source clock directly.
180 *
181 * After this function, please call ref CLOCK_SetXtal0Freq to inform clock driver
182 * the external clock frequency.
183 *
184 * param bypassXtalOsc Pass in true to bypass the external crystal oscillator.
185 * note This device does not support bypass external crystal oscillator, so
186 * the input parameter should always be false.
187 */
188void CLOCK_InitExternalClk(bool bypassXtalOsc)
189{
190 /* This device does not support bypass XTAL OSC. */
191 assert(!bypassXtalOsc);
192
193 CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */
194 while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0UL)
195 {
196 }
197 CCM_ANALOG->MISC0_SET = (uint32_t)CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */
198 while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0UL)
199 {
200 }
201 CCM_ANALOG->MISC0_CLR = (uint32_t)CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK;
202}
203
204/*!
205 * brief Deinitialize the external 24MHz clock.
206 *
207 * This function disables the external 24MHz clock.
208 *
209 * After this function, please call ref CLOCK_SetXtal0Freq to set external clock
210 * frequency to 0.
211 */
212void CLOCK_DeinitExternalClk(void)
213{
214 CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power down */
215}
216
217/*!
218 * brief Switch the OSC.
219 *
220 * This function switches the OSC source for SoC.
221 *
222 * param osc OSC source to switch to.
223 */
224void CLOCK_SwitchOsc(clock_osc_t osc)
225{
226 if (osc == kCLOCK_RcOsc)
227 {
228 XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK;
229 }
230 else
231 {
232 XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK;
233 }
234}
235
236/*!
237 * brief Initialize the RC oscillator 24MHz clock.
238 */
239void CLOCK_InitRcOsc24M(void)
240{
241 XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK;
242}
243
244/*!
245 * brief Power down the RCOSC 24M clock.
246 */
247void CLOCK_DeinitRcOsc24M(void)
248{
249 XTALOSC24M->LOWPWR_CTRL &= ~XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK;
250}
251
252/*!
253 * brief Gets the AHB clock frequency.
254 *
255 * return The AHB clock frequency value in hertz.
256 */
257uint32_t CLOCK_GetAhbFreq(void)
258{
259 return CLOCK_GetPeriphClkFreq() / (((CCM->CBCDR & CCM_CBCDR_AHB_PODF_MASK) >> CCM_CBCDR_AHB_PODF_SHIFT) + 1U);
260}
261
262/*!
263 * brief Gets the SEMC clock frequency.
264 *
265 * return The SEMC clock frequency value in hertz.
266 */
267uint32_t CLOCK_GetSemcFreq(void)
268{
269 uint32_t freq;
270
271 /* SEMC alternative clock ---> SEMC Clock */
272 if ((CCM->CBCDR & CCM_CBCDR_SEMC_CLK_SEL_MASK) != 0UL)
273 {
274 /* PLL3 PFD1 ---> SEMC alternative clock ---> SEMC Clock */
275 if ((CCM->CBCDR & CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK) != 0UL)
276 {
277 freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1);
278 }
279 /* PLL2 PFD2 ---> SEMC alternative clock ---> SEMC Clock */
280 else
281 {
282 freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2);
283 }
284 }
285 /* Periph_clk ---> SEMC Clock */
286 else
287 {
288 freq = CLOCK_GetPeriphClkFreq();
289 }
290
291 freq /= (((CCM->CBCDR & CCM_CBCDR_SEMC_PODF_MASK) >> CCM_CBCDR_SEMC_PODF_SHIFT) + 1U);
292
293 return freq;
294}
295
296/*!
297 * brief Gets the IPG clock frequency.
298 *
299 * return The IPG clock frequency value in hertz.
300 */
301uint32_t CLOCK_GetIpgFreq(void)
302{
303 return CLOCK_GetAhbFreq() / (((CCM->CBCDR & CCM_CBCDR_IPG_PODF_MASK) >> CCM_CBCDR_IPG_PODF_SHIFT) + 1U);
304}
305
306/*!
307 * brief Gets the PER clock frequency.
308 *
309 * return The PER clock frequency value in hertz.
310 */
311uint32_t CLOCK_GetPerClkFreq(void)
312{
313 uint32_t freq;
314
315 /* Osc_clk ---> PER Clock*/
316 if ((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL_MASK) != 0UL)
317 {
318 freq = CLOCK_GetOscFreq();
319 }
320 /* Periph_clk ---> AHB Clock ---> IPG Clock ---> PER Clock */
321 else
322 {
323 freq = CLOCK_GetIpgFreq();
324 }
325
326 freq /= (((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_PODF_MASK) >> CCM_CSCMR1_PERCLK_PODF_SHIFT) + 1U);
327
328 return freq;
329}
330
331/*!
332 * brief Gets the clock frequency for a specific clock name.
333 *
334 * This function checks the current clock configurations and then calculates
335 * the clock frequency for a specific clock name defined in clock_name_t.
336 *
337 * param clockName Clock names defined in clock_name_t
338 * return Clock frequency value in hertz
339 */
340uint32_t CLOCK_GetFreq(clock_name_t name)
341{
342 uint32_t freq;
343
344 switch (name)
345 {
346 case kCLOCK_CpuClk:
347 case kCLOCK_AhbClk:
348 freq = CLOCK_GetAhbFreq();
349 break;
350
351 case kCLOCK_SemcClk:
352 freq = CLOCK_GetSemcFreq();
353 break;
354
355 case kCLOCK_IpgClk:
356 freq = CLOCK_GetIpgFreq();
357 break;
358
359 case kCLOCK_PerClk:
360 freq = CLOCK_GetPerClkFreq();
361 break;
362
363 case kCLOCK_OscClk:
364 freq = CLOCK_GetOscFreq();
365 break;
366 case kCLOCK_RtcClk:
367 freq = CLOCK_GetRtcFreq();
368 break;
369 case kCLOCK_Usb1PllClk:
370 freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
371 break;
372 case kCLOCK_Usb1PllPfd0Clk:
373 freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd0);
374 break;
375 case kCLOCK_Usb1PllPfd1Clk:
376 freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1);
377 break;
378 case kCLOCK_Usb1PllPfd2Clk:
379 freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd2);
380 break;
381 case kCLOCK_Usb1PllPfd3Clk:
382 freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd3);
383 break;
384 case kCLOCK_Usb1SwClk:
385 freq = CLOCK_GetPllUsb1SWFreq();
386 break;
387 case kCLOCK_Usb1Sw60MClk:
388 freq = CLOCK_GetPllUsb1SWFreq() / 8UL;
389 break;
390 case kCLOCK_Usb1Sw80MClk:
391 freq = CLOCK_GetPllUsb1SWFreq() / 6UL;
392 break;
393
394 case kCLOCK_SysPllClk:
395 freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
396 break;
397 case kCLOCK_SysPllPfd0Clk:
398 freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0);
399 break;
400 case kCLOCK_SysPllPfd1Clk:
401 freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd1);
402 break;
403 case kCLOCK_SysPllPfd2Clk:
404 freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2);
405 break;
406 case kCLOCK_SysPllPfd3Clk:
407 freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd3);
408 break;
409 case kCLOCK_EnetPllClk:
410 freq = CLOCK_GetPllFreq(kCLOCK_PllEnet);
411 break;
412 case kCLOCK_EnetPll25MClk:
413 freq = CLOCK_GetPllFreq(kCLOCK_PllEnet25M);
414 break;
415 case kCLOCK_EnetPll500MClk:
416 freq = CLOCK_GetPllFreq(kCLOCK_PllEnet500M);
417 break;
418 case kCLOCK_AudioPllClk:
419 freq = CLOCK_GetPllFreq(kCLOCK_PllAudio);
420 break;
421 default:
422 freq = 0U;
423 break;
424 }
425
426 return freq;
427}
428
429/*!
430 * brief Gets the frequency of selected clock root.
431 *
432 * param clockRoot The clock root used to get the frequency, please refer to @ref clock_root_t.
433 * return The frequency of selected clock root.
434 */
435uint32_t CLOCK_GetClockRootFreq(clock_root_t clockRoot)
436{
437 const clock_name_t clockRootSourceArray[][4] = CLOCK_ROOT_SOUCE;
438 const clock_mux_t clockRootMuxTupleArray[] = CLOCK_ROOT_MUX_TUPLE;
439 const clock_div_t clockRootDivTupleArray[][2] = CLOCK_ROOT_DIV_TUPLE;
440 uint32_t freq = 0UL;
441 clock_mux_t clockRootMuxTuple = clockRootMuxTupleArray[(uint8_t)clockRoot];
442 clock_div_t clockRootPreDivTuple = clockRootDivTupleArray[(uint8_t)clockRoot][0];
443 clock_div_t clockRootPostDivTuple = clockRootDivTupleArray[(uint8_t)clockRoot][1];
444 uint32_t clockRootMuxValue = (CCM_TUPLE_REG(CCM, clockRootMuxTuple) & CCM_TUPLE_MASK(clockRootMuxTuple)) >>
445 CCM_TUPLE_SHIFT(clockRootMuxTuple);
446 clock_name_t clockSourceName;
447
448 clockSourceName = clockRootSourceArray[(uint8_t)clockRoot][clockRootMuxValue];
449
450 assert(clockSourceName != kCLOCK_NoneName);
451
452 freq = CLOCK_GetFreq(clockSourceName);
453
454 if (clockRootPreDivTuple != kCLOCK_NonePreDiv)
455 {
456 freq /= ((CCM_TUPLE_REG(CCM, clockRootPreDivTuple) & CCM_TUPLE_MASK(clockRootPreDivTuple)) >>
457 CCM_TUPLE_SHIFT(clockRootPreDivTuple)) +
458 1UL;
459 }
460
461 freq /= ((CCM_TUPLE_REG(CCM, clockRootPostDivTuple) & CCM_TUPLE_MASK(clockRootPostDivTuple)) >>
462 CCM_TUPLE_SHIFT(clockRootPostDivTuple)) +
463 1UL;
464
465 return freq;
466}
467
468/*! brief Enable USB HS clock.
469 *
470 * This function only enables the access to USB HS prepheral, upper layer
471 * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
472 * clock to use USB HS.
473 *
474 * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused.
475 * param freq USB HS does not care about the clock source, so this parameter is ignored.
476 * retval true The clock is set successfully.
477 * retval false The clock source is invalid to get proper USB HS clock.
478 */
479bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq)
480{
481 uint32_t i;
482 CCM->CCGR6 |= CCM_CCGR6_CG0_MASK;
483 USB->USBCMD |= USBHS_USBCMD_RST_MASK;
484
485 /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
486 for (i = 0; i < 400000UL; i++)
487 {
488 __ASM("nop");
489 }
490 PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) |
491 (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK);
492 return true;
493}
494
495/*! brief Enable USB HS PHY PLL clock.
496 *
497 * This function enables the internal 480MHz USB PHY PLL clock.
498 *
499 * param src USB HS PHY PLL clock source.
500 * param freq The frequency specified by src.
501 * retval true The clock is set successfully.
502 * retval false The clock source is invalid to get proper USB HS clock.
503 */
504bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
505{
506 const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
507 if ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_ENABLE_MASK) != 0UL)
508 {
509 CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
510 }
511 else
512 {
513 CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
514 }
515 USBPHY->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */
516 USBPHY->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK;
517
518 USBPHY->PWD = 0;
519 USBPHY->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK |
520 USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK;
521 return true;
522}
523
524/*! brief Disable USB HS PHY PLL clock.
525 *
526 * This function disables USB HS PHY PLL clock.
527 */
528void CLOCK_DisableUsbhs0PhyPllClock(void)
529{
530 CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
531 USBPHY->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */
532}
533
534/*!
535 * brief Initialize the System PLL.
536 *
537 * This function initializes the System PLL with specific settings
538 *
539 * param config Configuration to set to PLL.
540 */
541void CLOCK_InitSysPll(const clock_sys_pll_config_t *config)
542{
543 /* Bypass PLL first */
544 CCM_ANALOG->PLL_SYS = (CCM_ANALOG->PLL_SYS & (~CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_MASK)) |
545 CCM_ANALOG_PLL_SYS_BYPASS_MASK | CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC(config->src);
546
547 CCM_ANALOG->PLL_SYS =
548 (CCM_ANALOG->PLL_SYS & (~(CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK | CCM_ANALOG_PLL_SYS_POWERDOWN_MASK))) |
549 CCM_ANALOG_PLL_SYS_ENABLE_MASK | CCM_ANALOG_PLL_SYS_DIV_SELECT(config->loopDivider);
550
551 /* Initialize the fractional mode */
552 CCM_ANALOG->PLL_SYS_NUM = CCM_ANALOG_PLL_SYS_NUM_A(config->numerator);
553 CCM_ANALOG->PLL_SYS_DENOM = CCM_ANALOG_PLL_SYS_DENOM_B(config->denominator);
554
555 /* Initialize the spread spectrum mode */
556 CCM_ANALOG->PLL_SYS_SS = CCM_ANALOG_PLL_SYS_SS_STEP(config->ss_step) |
557 CCM_ANALOG_PLL_SYS_SS_ENABLE(config->ss_enable) |
558 CCM_ANALOG_PLL_SYS_SS_STOP(config->ss_stop);
559
560 while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0UL)
561 {
562 }
563
564 /* Disable Bypass */
565 CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_BYPASS_MASK;
566}
567
568/*!
569 * brief De-initialize the System PLL.
570 */
571void CLOCK_DeinitSysPll(void)
572{
573 CCM_ANALOG->PLL_SYS = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK;
574}
575
576/*!
577 * brief Initialize the USB1 PLL.
578 *
579 * This function initializes the USB1 PLL with specific settings
580 *
581 * param config Configuration to set to PLL.
582 */
583void CLOCK_InitUsb1Pll(const clock_usb_pll_config_t *config)
584{
585 /* Bypass PLL first */
586 CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK)) |
587 CCM_ANALOG_PLL_USB1_BYPASS_MASK | CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC(config->src);
588
589 CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK)) |
590 CCM_ANALOG_PLL_USB1_ENABLE_MASK | CCM_ANALOG_PLL_USB1_POWER_MASK |
591 CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB1_DIV_SELECT(config->loopDivider);
592
593 while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0UL)
594 {
595 }
596
597 /* Disable Bypass */
598 CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK;
599}
600
601/*!
602 * brief Deinitialize the USB1 PLL.
603 */
604void CLOCK_DeinitUsb1Pll(void)
605{
606 CCM_ANALOG->PLL_USB1 = 0U;
607}
608
609/*!
610 * brief Initializes the Audio PLL.
611 *
612 * This function initializes the Audio PLL with specific settings
613 *
614 * param config Configuration to set to PLL.
615 */
616void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
617{
618 uint32_t pllAudio;
619 uint32_t misc2 = 0;
620
621 /* Bypass PLL first */
622 CCM_ANALOG->PLL_AUDIO = (CCM_ANALOG->PLL_AUDIO & (~CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC_MASK)) |
623 CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(config->src);
624
625 CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(config->numerator);
626 CCM_ANALOG->PLL_AUDIO_DENOM = CCM_ANALOG_PLL_AUDIO_DENOM_B(config->denominator);
627
628 /*
629 * Set post divider:
630 *
631 * ------------------------------------------------------------------------
632 * | config->postDivider | PLL_AUDIO[POST_DIV_SELECT] | MISC2[AUDIO_DIV] |
633 * ------------------------------------------------------------------------
634 * | 1 | 2 | 0 |
635 * ------------------------------------------------------------------------
636 * | 2 | 1 | 0 |
637 * ------------------------------------------------------------------------
638 * | 4 | 2 | 3 |
639 * ------------------------------------------------------------------------
640 * | 8 | 1 | 3 |
641 * ------------------------------------------------------------------------
642 * | 16 | 0 | 3 |
643 * ------------------------------------------------------------------------
644 */
645 pllAudio =
646 (CCM_ANALOG->PLL_AUDIO & (~(CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK | CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK))) |
647 CCM_ANALOG_PLL_AUDIO_ENABLE_MASK | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(config->loopDivider);
648
649 switch (config->postDivider)
650 {
651 case 16:
652 pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0);
653 misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
654 break;
655
656 case 8:
657 pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1);
658 misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
659 break;
660
661 case 4:
662 pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2);
663 misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
664 break;
665
666 case 2:
667 pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1);
668 break;
669
670 default:
671 pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2);
672 break;
673 }
674
675 CCM_ANALOG->MISC2 =
676 (CCM_ANALOG->MISC2 & ~(CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK)) | misc2;
677
678 CCM_ANALOG->PLL_AUDIO = pllAudio;
679
680 while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0UL)
681 {
682 }
683
684 /* Disable Bypass */
685 CCM_ANALOG->PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_BYPASS_MASK;
686}
687
688/*!
689 * brief De-initialize the Audio PLL.
690 */
691void CLOCK_DeinitAudioPll(void)
692{
693 CCM_ANALOG->PLL_AUDIO = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK;
694}
695
696/*!
697 * brief Initialize the ENET PLL.
698 *
699 * This function initializes the ENET PLL with specific settings.
700 *
701 * param config Configuration to set to PLL.
702 */
703void CLOCK_InitEnetPll(const clock_enet_pll_config_t *config)
704{
705 uint32_t enet_pll = CCM_ANALOG_PLL_ENET_DIV_SELECT(config->loopDivider);
706
707 CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK)) |
708 CCM_ANALOG_PLL_ENET_BYPASS_MASK | CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(config->src);
709
710 if (config->enableClkOutput)
711 {
712 enet_pll |= CCM_ANALOG_PLL_ENET_ENABLE_MASK;
713 }
714
715 if (config->enableClkOutput25M)
716 {
717 enet_pll |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK;
718 }
719
720 if (config->enableClkOutput500M)
721 {
722 enet_pll |= CCM_ANALOG_PLL_ENET_ENET_500M_REF_EN_MASK;
723 }
724
725 CCM_ANALOG->PLL_ENET =
726 (CCM_ANALOG->PLL_ENET & (~(CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK))) |
727 enet_pll;
728
729 /* Wait for stable */
730 while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0UL)
731 {
732 }
733
734 /* Disable Bypass */
735 CCM_ANALOG->PLL_ENET &= ~CCM_ANALOG_PLL_ENET_BYPASS_MASK;
736}
737
738/*!
739 * brief Deinitialize the ENET PLL.
740 *
741 * This function disables the ENET PLL.
742 */
743void CLOCK_DeinitEnetPll(void)
744{
745 CCM_ANALOG->PLL_ENET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK;
746}
747
748/*!
749 * brief Get current PLL output frequency.
750 *
751 * This function get current output frequency of specific PLL
752 *
753 * param pll pll name to get frequency.
754 * return The PLL output frequency in hertz.
755 */
756uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
757{
758 uint32_t freq;
759 uint32_t divSelect;
760 clock_64b_t freqTmp;
761
762 const uint32_t enetRefClkFreq[] = {
763 25000000U, /* 25M */
764 50000000U, /* 50M */
765 100000000U, /* 100M */
766 125000000U /* 125M */
767 };
768
769 /* check if PLL is enabled */
770 if (!CLOCK_IsPllEnabled(CCM_ANALOG, pll))
771 {
772 return 0U;
773 }
774
775 /* get pll reference clock */
776 freq = CLOCK_GetPllBypassRefClk(CCM_ANALOG, pll);
777
778 /* check if pll is bypassed */
779 if (CLOCK_IsPllBypassed(CCM_ANALOG, pll))
780 {
781 return freq;
782 }
783
784 switch (pll)
785 {
786 case kCLOCK_PllSys:
787 /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
788 freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_SYS_NUM)));
789 freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_SYS_DENOM));
790
791 if ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK) != 0UL)
792 {
793 freq *= 22U;
794 }
795 else
796 {
797 freq *= 20U;
798 }
799
800 freq += (uint32_t)freqTmp;
801 break;
802
803 case kCLOCK_PllUsb1:
804 freq = (freq * (((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) != 0UL) ? 22U : 20U));
805 break;
806
807 case kCLOCK_PllAudio:
808 /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
809 divSelect =
810 (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_AUDIO_DIV_SELECT_SHIFT;
811
812 freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_NUM)));
813 freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_DENOM));
814
815 freq = freq * divSelect + (uint32_t)freqTmp;
816
817 /* AUDIO PLL output = PLL output frequency / POSTDIV. */
818
819 /*
820 * Post divider:
821 *
822 * PLL_AUDIO[POST_DIV_SELECT]:
823 * 0x00: 4
824 * 0x01: 2
825 * 0x02: 1
826 *
827 * MISC2[AUDO_DIV]:
828 * 0x00: 1
829 * 0x01: 2
830 * 0x02: 1
831 * 0x03: 4
832 */
833 switch (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT_MASK)
834 {
835 case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0U):
836 freq = freq >> 2U;
837 break;
838
839 case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1U):
840 freq = freq >> 1U;
841 break;
842
843 case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2U):
844 freq = freq >> 0U;
845 break;
846
847 default:
848 assert(false);
849 break;
850 }
851
852 switch (CCM_ANALOG->MISC2 & (CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK))
853 {
854 case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1):
855 freq >>= 2U;
856 break;
857
858 case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1):
859 freq >>= 1U;
860 break;
861
862 case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0):
863 case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0):
864 freq >>= 0U;
865 break;
866
867 default:
868 assert(false);
869 break;
870 }
871 break;
872
873 case kCLOCK_PllEnet:
874 divSelect =
875 (CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_ENET_DIV_SELECT_SHIFT;
876 freq = enetRefClkFreq[divSelect];
877 break;
878
879 case kCLOCK_PllEnet25M:
880 /* ref_enetpll1 if fixed at 25MHz. */
881 freq = 25000000UL;
882 break;
883
884 case kCLOCK_PllEnet500M:
885 /* PLL6 is fixed at 25MHz. */
886 freq = 500000000UL;
887 break;
888
889 default:
890 freq = 0U;
891 break;
892 }
893
894 return freq;
895}
896
897/*!
898 * brief Initialize the System PLL PFD.
899 *
900 * This function initializes the System PLL PFD. During new value setting,
901 * the clock output is disabled to prevent glitch.
902 *
903 * param pfd Which PFD clock to enable.
904 * param pfdFrac The PFD FRAC value.
905 * note It is recommended that PFD settings are kept between 12-35.
906 */
907void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t pfdFrac)
908{
909 uint32_t pfdIndex = (uint32_t)pfd;
910 uint32_t pfd528;
911
912 pfd528 = CCM_ANALOG->PFD_528 &
913 ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | (uint32_t)CCM_ANALOG_PFD_528_PFD0_FRAC_MASK)
914 << (8UL * pfdIndex)));
915
916 /* Disable the clock output first. */
917 CCM_ANALOG->PFD_528 = pfd528 | ((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
918
919 /* Set the new value and enable output. */
920 CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex));
921}
922
923/*!
924 * brief De-initialize the System PLL PFD.
925 *
926 * This function disables the System PLL PFD.
927 *
928 * param pfd Which PFD clock to disable.
929 */
930void CLOCK_DeinitSysPfd(clock_pfd_t pfd)
931{
932 CCM_ANALOG->PFD_528 |= (uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8UL * (uint32_t)pfd);
933}
934
935/*!
936 * brief Initialize the USB1 PLL PFD.
937 *
938 * This function initializes the USB1 PLL PFD. During new value setting,
939 * the clock output is disabled to prevent glitch.
940 *
941 * param pfd Which PFD clock to enable.
942 * param pfdFrac The PFD FRAC value.
943 * note It is recommended that PFD settings are kept between 12-35.
944 */
945void CLOCK_InitUsb1Pfd(clock_pfd_t pfd, uint8_t pfdFrac)
946{
947 uint32_t pfdIndex = (uint32_t)pfd;
948 uint32_t pfd480;
949
950 pfd480 = CCM_ANALOG->PFD_480 &
951 ~((uint32_t)((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | (uint32_t)CCM_ANALOG_PFD_480_PFD0_FRAC_MASK)
952 << (8UL * pfdIndex));
953
954 /* Disable the clock output first. */
955 CCM_ANALOG->PFD_480 = pfd480 | ((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
956
957 /* Set the new value and enable output. */
958 CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex));
959}
960
961/*!
962 * brief De-initialize the USB1 PLL PFD.
963 *
964 * This function disables the USB1 PLL PFD.
965 *
966 * param pfd Which PFD clock to disable.
967 */
968void CLOCK_DeinitUsb1Pfd(clock_pfd_t pfd)
969{
970 CCM_ANALOG->PFD_480 |= (uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * (uint32_t)pfd);
971}
972
973/*!
974 * brief Get current System PLL PFD output frequency.
975 *
976 * This function get current output frequency of specific System PLL PFD
977 *
978 * param pfd pfd name to get frequency.
979 * return The PFD output frequency in hertz.
980 */
981uint32_t CLOCK_GetSysPfdFreq(clock_pfd_t pfd)
982{
983 uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
984
985 switch (pfd)
986 {
987 case kCLOCK_Pfd0:
988 freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD0_FRAC_SHIFT);
989 break;
990
991 case kCLOCK_Pfd1:
992 freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD1_FRAC_SHIFT);
993 break;
994
995 case kCLOCK_Pfd2:
996 freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD2_FRAC_SHIFT);
997 break;
998
999 case kCLOCK_Pfd3:
1000 freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD3_FRAC_SHIFT);
1001 break;
1002
1003 default:
1004 freq = 0U;
1005 break;
1006 }
1007 freq *= 18U;
1008
1009 return freq;
1010}
1011
1012/*!
1013 * brief Get current USB1 PLL PFD output frequency.
1014 *
1015 * This function get current output frequency of specific USB1 PLL PFD
1016 *
1017 * param pfd pfd name to get frequency.
1018 * return The PFD output frequency in hertz.
1019 */
1020uint32_t CLOCK_GetUsb1PfdFreq(clock_pfd_t pfd)
1021{
1022 uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
1023
1024 switch (pfd)
1025 {
1026 case kCLOCK_Pfd0:
1027 freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT);
1028 break;
1029
1030 case kCLOCK_Pfd1:
1031 freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD1_FRAC_SHIFT);
1032 break;
1033
1034 case kCLOCK_Pfd2:
1035 freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD2_FRAC_SHIFT);
1036 break;
1037
1038 case kCLOCK_Pfd3:
1039 freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD3_FRAC_SHIFT);
1040 break;
1041
1042 default:
1043 freq = 0U;
1044 break;
1045 }
1046 freq *= 18U;
1047
1048 return freq;
1049}
1050
1051/*!
1052 * brief Set the clock source and the divider of the clock output1.
1053 *
1054 * param selection The clock source to be output, please refer to clock_output1_selection_t.
1055 * param divider The divider of the output clock signal, please refer to clock_output_divider_t.
1056 */
1057void CLOCK_SetClockOutput1(clock_output1_selection_t selection, clock_output_divider_t divider)
1058{
1059 uint32_t tmp32;
1060
1061 tmp32 = CCM->CCOSR;
1062 if (selection == kCLOCK_DisableClockOutput1)
1063 {
1064 tmp32 &= ~CCM_CCOSR_CLKO1_EN_MASK;
1065 }
1066 else
1067 {
1068 tmp32 |= CCM_CCOSR_CLKO1_EN_MASK;
1069 tmp32 &= ~(CCM_CCOSR_CLKO1_SEL_MASK | CCM_CCOSR_CLKO1_DIV_MASK);
1070 tmp32 |= CCM_CCOSR_CLKO1_SEL(selection) | CCM_CCOSR_CLKO1_DIV(divider);
1071 }
1072 CCM->CCOSR = tmp32;
1073}
1074
1075/*!
1076 * brief Set the clock source and the divider of the clock output2.
1077 *
1078 * param selection The clock source to be output, please refer to clock_output2_selection_t.
1079 * param divider The divider of the output clock signal, please refer to clock_output_divider_t.
1080 */
1081void CLOCK_SetClockOutput2(clock_output2_selection_t selection, clock_output_divider_t divider)
1082{
1083 uint32_t tmp32;
1084
1085 tmp32 = CCM->CCOSR;
1086 if (selection == kCLOCK_DisableClockOutput2)
1087 {
1088 tmp32 &= CCM_CCOSR_CLKO2_EN_MASK;
1089 }
1090 else
1091 {
1092 tmp32 |= CCM_CCOSR_CLKO2_EN_MASK;
1093 tmp32 &= ~(CCM_CCOSR_CLKO2_SEL_MASK | CCM_CCOSR_CLKO2_DIV_MASK);
1094 tmp32 |= CCM_CCOSR_CLKO2_SEL(selection) | CCM_CCOSR_CLKO2_DIV(divider);
1095 }
1096
1097 CCM->CCOSR = tmp32;
1098}
1099
1100/*!
1101 * brief Get the frequency of clock output1 clock signal.
1102 *
1103 * return The frequency of clock output1 clock signal.
1104 */
1105uint32_t CLOCK_GetClockOutCLKO1Freq(void)
1106{
1107 uint32_t freq = 0U;
1108 uint32_t tmp32;
1109
1110 tmp32 = CCM->CCOSR;
1111
1112 if ((tmp32 & CCM_CCOSR_CLKO1_EN_MASK) != 0UL)
1113 {
1114 switch ((tmp32 & CCM_CCOSR_CLKO1_SEL_MASK) >> CCM_CCOSR_CLKO1_SEL_SHIFT)
1115 {
1116 case (uint32_t)kCLOCK_OutputPllUsb1Sw:
1117 freq = CLOCK_GetPllUsb1SWFreq() / 2UL;
1118 break;
1119 case (uint32_t)kCLOCK_OutputPllSys:
1120 freq = CLOCK_GetPllFreq(kCLOCK_PllSys) / 2UL;
1121 break;
1122 case (uint32_t)kCLOCK_OutputPllENET500M:
1123 freq = CLOCK_GetPllFreq(kCLOCK_PllEnet500M) / 2UL;
1124 break;
1125 case (uint32_t)kCLOCK_OutputSemcClk:
1126 freq = CLOCK_GetSemcFreq();
1127 break;
1128 case (uint32_t)kCLOCK_OutputAhbClk:
1129 freq = CLOCK_GetAhbFreq();
1130 break;
1131 case (uint32_t)kCLOCK_OutputIpgClk:
1132 freq = CLOCK_GetIpgFreq();
1133 break;
1134 case (uint32_t)kCLOCK_OutputPerClk:
1135 freq = CLOCK_GetPerClkFreq();
1136 break;
1137 case (uint32_t)kCLOCK_OutputPll4MainClk:
1138 freq = CLOCK_GetPllFreq(kCLOCK_PllAudio);
1139 break;
1140 default:
1141 /* This branch should never be hit. */
1142 break;
1143 }
1144
1145 freq /= (((tmp32 & CCM_CCOSR_CLKO1_DIV_MASK) >> CCM_CCOSR_CLKO1_DIV_SHIFT) + 1U);
1146 }
1147 else
1148 {
1149 freq = 0UL;
1150 }
1151
1152 return freq;
1153}
1154
1155/*!
1156 * brief Get the frequency of clock output2 clock signal.
1157 *
1158 * return The frequency of clock output2 clock signal.
1159 */
1160uint32_t CLOCK_GetClockOutClkO2Freq(void)
1161{
1162 uint32_t freq = 0U;
1163 uint32_t tmp32;
1164
1165 tmp32 = CCM->CCOSR;
1166
1167 if ((tmp32 & CCM_CCOSR_CLKO2_EN_MASK) != 0UL)
1168 {
1169 switch ((tmp32 & CCM_CCOSR_CLKO2_SEL_MASK) >> CCM_CCOSR_CLKO2_SEL_SHIFT)
1170 {
1171 case (uint32_t)kCLOCK_OutputUsdhc1Clk:
1172 freq = CLOCK_GetClockRootFreq(kCLOCK_Usdhc1ClkRoot);
1173 break;
1174 case (uint32_t)kCLOCK_OutputLpi2cClk:
1175 freq = CLOCK_GetClockRootFreq(kCLOCK_Lpi2cClkRoot);
1176 break;
1177 case (uint32_t)kCLOCK_OutputOscClk:
1178 freq = CLOCK_GetOscFreq();
1179 break;
1180 case (uint32_t)kCLOCK_OutputLpspiClk:
1181 freq = CLOCK_GetClockRootFreq(kCLOCK_LpspiClkRoot);
1182 break;
1183 case (uint32_t)kCLOCK_OutputUsdhc2Clk:
1184 freq = CLOCK_GetClockRootFreq(kCLOCK_Usdhc2ClkRoot);
1185 break;
1186 case (uint32_t)kCLOCK_OutputSai1Clk:
1187 freq = CLOCK_GetClockRootFreq(kCLOCK_Sai1ClkRoot);
1188 break;
1189 case (uint32_t)kCLOCK_OutputSai2Clk:
1190 freq = CLOCK_GetClockRootFreq(kCLOCK_Sai2ClkRoot);
1191 break;
1192 case (uint32_t)kCLOCK_OutputSai3Clk:
1193 freq = CLOCK_GetClockRootFreq(kCLOCK_Sai3ClkRoot);
1194 break;
1195 case (uint32_t)kCLOCK_OutputTraceClk:
1196 freq = CLOCK_GetClockRootFreq(kCLOCK_TraceClkRoot);
1197 break;
1198 case (uint32_t)kCLOCK_OutputCanClk:
1199 freq = CLOCK_GetClockRootFreq(kCLOCK_CanClkRoot);
1200 break;
1201 case (uint32_t)kCLOCK_OutputFlexspiClk:
1202 freq = CLOCK_GetClockRootFreq(kCLOCK_FlexspiClkRoot);
1203 break;
1204 case (uint32_t)kCLOCK_OutputUartClk:
1205 freq = CLOCK_GetClockRootFreq(kCLOCK_UartClkRoot);
1206 break;
1207 case (uint32_t)kCLOCK_OutputSpdif0Clk:
1208 freq = CLOCK_GetClockRootFreq(kCLOCK_SpdifClkRoot);
1209 break;
1210 default:
1211 /* This branch should never be hit. */
1212 break;
1213 }
1214
1215 freq /= (((tmp32 & CCM_CCOSR_CLKO2_DIV_MASK) >> CCM_CCOSR_CLKO2_DIV_SHIFT) + 1U);
1216 }
1217 else
1218 {
1219 freq = 0UL;
1220 }
1221
1222 return freq;
1223}