diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1061/drivers/fsl_clock.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1061/drivers/fsl_clock.c | 1526 |
1 files changed, 1526 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1061/drivers/fsl_clock.c b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1061/drivers/fsl_clock.c new file mode 100644 index 000000000..181c766b4 --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT1061/drivers/fsl_clock.c | |||
@@ -0,0 +1,1526 @@ | |||
1 | /* | ||
2 | * Copyright 2018 - 2019 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 | ||
18 | achieve better performance, it is depend on the IDE Floating point settings, if double precision is selected | ||
19 | in 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*/ | ||
26 | typedef double clock_64b_t; | ||
27 | #else | ||
28 | typedef 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*/ | ||
34 | typedef double clock_64b_t; | ||
35 | #else | ||
36 | typedef uint64_t clock_64b_t; | ||
37 | #endif | ||
38 | |||
39 | #elif defined(__CC_ARM) || defined(__ARMCC_VERSION) | ||
40 | |||
41 | #if defined __TARGET_FPU_FPV5_D16 | ||
42 | typedef double clock_64b_t; | ||
43 | #else | ||
44 | typedef uint64_t clock_64b_t; | ||
45 | #endif | ||
46 | |||
47 | #else | ||
48 | typedef uint64_t clock_64b_t; | ||
49 | #endif | ||
50 | |||
51 | #else | ||
52 | typedef uint64_t clock_64b_t; | ||
53 | #endif | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * Variables | ||
57 | ******************************************************************************/ | ||
58 | |||
59 | /* External XTAL (OSC) clock frequency. */ | ||
60 | volatile uint32_t g_xtalFreq; | ||
61 | /* External RTC XTAL clock frequency. */ | ||
62 | volatile 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 | */ | ||
73 | static 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 | */ | ||
80 | static uint32_t CLOCK_GetPllUsb1SWFreq(void); | ||
81 | |||
82 | /******************************************************************************* | ||
83 | * Code | ||
84 | ******************************************************************************/ | ||
85 | |||
86 | static 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) != 0U) | ||
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 ---> Pre_Periph_clk ---> Periph_clk */ | ||
123 | case CCM_CBCMR_PRE_PERIPH_CLK_SEL(0U): | ||
124 | freq = CLOCK_GetPllFreq(kCLOCK_PllSys); | ||
125 | break; | ||
126 | |||
127 | /* PLL2 PFD2 ---> Pre_Periph_clk ---> Periph_clk */ | ||
128 | case CCM_CBCMR_PRE_PERIPH_CLK_SEL(1U): | ||
129 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); | ||
130 | break; | ||
131 | |||
132 | /* PLL2 PFD0 ---> Pre_Periph_clk ---> Periph_clk */ | ||
133 | case CCM_CBCMR_PRE_PERIPH_CLK_SEL(2U): | ||
134 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0); | ||
135 | break; | ||
136 | |||
137 | /* PLL1 divided(/2) ---> Pre_Periph_clk ---> Periph_clk */ | ||
138 | case CCM_CBCMR_PRE_PERIPH_CLK_SEL(3U): | ||
139 | freq = CLOCK_GetPllFreq(kCLOCK_PllArm) / | ||
140 | (((CCM->CACRR & CCM_CACRR_ARM_PODF_MASK) >> CCM_CACRR_ARM_PODF_SHIFT) + 1U); | ||
141 | break; | ||
142 | |||
143 | default: | ||
144 | freq = 0U; | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | return freq; | ||
150 | } | ||
151 | |||
152 | static uint32_t CLOCK_GetPllUsb1SWFreq(void) | ||
153 | { | ||
154 | uint32_t freq; | ||
155 | |||
156 | switch ((CCM->CCSR & CCM_CCSR_PLL3_SW_CLK_SEL_MASK) >> CCM_CCSR_PLL3_SW_CLK_SEL_SHIFT) | ||
157 | { | ||
158 | case 0: | ||
159 | { | ||
160 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); | ||
161 | break; | ||
162 | } | ||
163 | case 1: | ||
164 | { | ||
165 | freq = 24000000UL; | ||
166 | break; | ||
167 | } | ||
168 | default: | ||
169 | freq = 0UL; | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | return freq; | ||
174 | } | ||
175 | |||
176 | /*! | ||
177 | * brief Initialize the external 24MHz clock. | ||
178 | * | ||
179 | * This function supports two modes: | ||
180 | * 1. Use external crystal oscillator. | ||
181 | * 2. Bypass the external crystal oscillator, using input source clock directly. | ||
182 | * | ||
183 | * After this function, please call ref CLOCK_SetXtal0Freq to inform clock driver | ||
184 | * the external clock frequency. | ||
185 | * | ||
186 | * param bypassXtalOsc Pass in true to bypass the external crystal oscillator. | ||
187 | * note This device does not support bypass external crystal oscillator, so | ||
188 | * the input parameter should always be false. | ||
189 | */ | ||
190 | void CLOCK_InitExternalClk(bool bypassXtalOsc) | ||
191 | { | ||
192 | /* This device does not support bypass XTAL OSC. */ | ||
193 | assert(!bypassXtalOsc); | ||
194 | |||
195 | CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */ | ||
196 | while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0U) | ||
197 | { | ||
198 | } | ||
199 | CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */ | ||
200 | while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0UL) | ||
201 | { | ||
202 | } | ||
203 | CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; | ||
204 | } | ||
205 | |||
206 | /*! | ||
207 | * brief Deinitialize the external 24MHz clock. | ||
208 | * | ||
209 | * This function disables the external 24MHz clock. | ||
210 | * | ||
211 | * After this function, please call ref CLOCK_SetXtal0Freq to set external clock | ||
212 | * frequency to 0. | ||
213 | */ | ||
214 | void CLOCK_DeinitExternalClk(void) | ||
215 | { | ||
216 | CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power down */ | ||
217 | } | ||
218 | |||
219 | /*! | ||
220 | * brief Switch the OSC. | ||
221 | * | ||
222 | * This function switches the OSC source for SoC. | ||
223 | * | ||
224 | * param osc OSC source to switch to. | ||
225 | */ | ||
226 | void CLOCK_SwitchOsc(clock_osc_t osc) | ||
227 | { | ||
228 | if (osc == kCLOCK_RcOsc) | ||
229 | { | ||
230 | XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK; | ||
231 | } | ||
232 | else | ||
233 | { | ||
234 | XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | /*! | ||
239 | * brief Initialize the RC oscillator 24MHz clock. | ||
240 | */ | ||
241 | void CLOCK_InitRcOsc24M(void) | ||
242 | { | ||
243 | XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; | ||
244 | } | ||
245 | |||
246 | /*! | ||
247 | * brief Power down the RCOSC 24M clock. | ||
248 | */ | ||
249 | void CLOCK_DeinitRcOsc24M(void) | ||
250 | { | ||
251 | XTALOSC24M->LOWPWR_CTRL &= ~XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; | ||
252 | } | ||
253 | |||
254 | /*! | ||
255 | * brief Gets the AHB clock frequency. | ||
256 | * | ||
257 | * return The AHB clock frequency value in hertz. | ||
258 | */ | ||
259 | uint32_t CLOCK_GetAhbFreq(void) | ||
260 | { | ||
261 | return CLOCK_GetPeriphClkFreq() / (((CCM->CBCDR & CCM_CBCDR_AHB_PODF_MASK) >> CCM_CBCDR_AHB_PODF_SHIFT) + 1U); | ||
262 | } | ||
263 | |||
264 | /*! | ||
265 | * brief Gets the SEMC clock frequency. | ||
266 | * | ||
267 | * return The SEMC clock frequency value in hertz. | ||
268 | */ | ||
269 | uint32_t CLOCK_GetSemcFreq(void) | ||
270 | { | ||
271 | uint32_t freq; | ||
272 | |||
273 | /* SEMC alternative clock ---> SEMC Clock */ | ||
274 | if ((CCM->CBCDR & CCM_CBCDR_SEMC_CLK_SEL_MASK) != 0U) | ||
275 | { | ||
276 | /* PLL3 PFD1 ---> SEMC alternative clock ---> SEMC Clock */ | ||
277 | if ((CCM->CBCDR & CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK) != 0U) | ||
278 | { | ||
279 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1); | ||
280 | } | ||
281 | /* PLL2 PFD2 ---> SEMC alternative clock ---> SEMC Clock */ | ||
282 | else | ||
283 | { | ||
284 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); | ||
285 | } | ||
286 | } | ||
287 | /* Periph_clk ---> SEMC Clock */ | ||
288 | else | ||
289 | { | ||
290 | freq = CLOCK_GetPeriphClkFreq(); | ||
291 | } | ||
292 | |||
293 | freq /= (((CCM->CBCDR & CCM_CBCDR_SEMC_PODF_MASK) >> CCM_CBCDR_SEMC_PODF_SHIFT) + 1U); | ||
294 | |||
295 | return freq; | ||
296 | } | ||
297 | |||
298 | /*! | ||
299 | * brief Gets the IPG clock frequency. | ||
300 | * | ||
301 | * return The IPG clock frequency value in hertz. | ||
302 | */ | ||
303 | uint32_t CLOCK_GetIpgFreq(void) | ||
304 | { | ||
305 | return CLOCK_GetAhbFreq() / (((CCM->CBCDR & CCM_CBCDR_IPG_PODF_MASK) >> CCM_CBCDR_IPG_PODF_SHIFT) + 1U); | ||
306 | } | ||
307 | |||
308 | /*! | ||
309 | * brief Gets the PER clock frequency. | ||
310 | * | ||
311 | * return The PER clock frequency value in hertz. | ||
312 | */ | ||
313 | uint32_t CLOCK_GetPerClkFreq(void) | ||
314 | { | ||
315 | uint32_t freq; | ||
316 | |||
317 | /* Osc_clk ---> PER Clock*/ | ||
318 | if ((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL_MASK) != 0U) | ||
319 | { | ||
320 | freq = CLOCK_GetOscFreq(); | ||
321 | } | ||
322 | /* Periph_clk ---> AHB Clock ---> IPG Clock ---> PER Clock */ | ||
323 | else | ||
324 | { | ||
325 | freq = CLOCK_GetIpgFreq(); | ||
326 | } | ||
327 | |||
328 | freq /= (((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_PODF_MASK) >> CCM_CSCMR1_PERCLK_PODF_SHIFT) + 1U); | ||
329 | |||
330 | return freq; | ||
331 | } | ||
332 | |||
333 | /*! | ||
334 | * brief Gets the clock frequency for a specific clock name. | ||
335 | * | ||
336 | * This function checks the current clock configurations and then calculates | ||
337 | * the clock frequency for a specific clock name defined in clock_name_t. | ||
338 | * | ||
339 | * param clockName Clock names defined in clock_name_t | ||
340 | * return Clock frequency value in hertz | ||
341 | */ | ||
342 | uint32_t CLOCK_GetFreq(clock_name_t name) | ||
343 | { | ||
344 | uint32_t freq; | ||
345 | |||
346 | switch (name) | ||
347 | { | ||
348 | case kCLOCK_CpuClk: | ||
349 | case kCLOCK_AhbClk: | ||
350 | freq = CLOCK_GetAhbFreq(); | ||
351 | break; | ||
352 | |||
353 | case kCLOCK_SemcClk: | ||
354 | freq = CLOCK_GetSemcFreq(); | ||
355 | break; | ||
356 | |||
357 | case kCLOCK_IpgClk: | ||
358 | freq = CLOCK_GetIpgFreq(); | ||
359 | break; | ||
360 | |||
361 | case kCLOCK_PerClk: | ||
362 | freq = CLOCK_GetPerClkFreq(); | ||
363 | break; | ||
364 | |||
365 | case kCLOCK_OscClk: | ||
366 | freq = CLOCK_GetOscFreq(); | ||
367 | break; | ||
368 | case kCLOCK_RtcClk: | ||
369 | freq = CLOCK_GetRtcFreq(); | ||
370 | break; | ||
371 | case kCLOCK_ArmPllClk: | ||
372 | freq = CLOCK_GetPllFreq(kCLOCK_PllArm); | ||
373 | break; | ||
374 | case kCLOCK_Usb1PllClk: | ||
375 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); | ||
376 | break; | ||
377 | case kCLOCK_Usb1PllPfd0Clk: | ||
378 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd0); | ||
379 | break; | ||
380 | case kCLOCK_Usb1PllPfd1Clk: | ||
381 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1); | ||
382 | break; | ||
383 | case kCLOCK_Usb1PllPfd2Clk: | ||
384 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd2); | ||
385 | break; | ||
386 | case kCLOCK_Usb1PllPfd3Clk: | ||
387 | freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd3); | ||
388 | break; | ||
389 | case kCLOCK_Usb1SwClk: | ||
390 | freq = CLOCK_GetPllUsb1SWFreq(); | ||
391 | break; | ||
392 | case kCLOCK_Usb1Sw120MClk: | ||
393 | freq = CLOCK_GetPllUsb1SWFreq() / 4UL; | ||
394 | break; | ||
395 | case kCLOCK_Usb1Sw60MClk: | ||
396 | freq = CLOCK_GetPllUsb1SWFreq() / 8UL; | ||
397 | break; | ||
398 | case kCLOCK_Usb1Sw80MClk: | ||
399 | freq = CLOCK_GetPllUsb1SWFreq() / 6UL; | ||
400 | break; | ||
401 | case kCLOCK_Usb2PllClk: | ||
402 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb2); | ||
403 | break; | ||
404 | case kCLOCK_SysPllClk: | ||
405 | freq = CLOCK_GetPllFreq(kCLOCK_PllSys); | ||
406 | break; | ||
407 | case kCLOCK_SysPllPfd0Clk: | ||
408 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0); | ||
409 | break; | ||
410 | case kCLOCK_SysPllPfd1Clk: | ||
411 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd1); | ||
412 | break; | ||
413 | case kCLOCK_SysPllPfd2Clk: | ||
414 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); | ||
415 | break; | ||
416 | case kCLOCK_SysPllPfd3Clk: | ||
417 | freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd3); | ||
418 | break; | ||
419 | case kCLOCK_EnetPll0Clk: | ||
420 | freq = CLOCK_GetPllFreq(kCLOCK_PllEnet); | ||
421 | break; | ||
422 | case kCLOCK_EnetPll1Clk: | ||
423 | freq = CLOCK_GetPllFreq(kCLOCK_PllEnet2); | ||
424 | break; | ||
425 | case kCLOCK_EnetPll2Clk: | ||
426 | freq = CLOCK_GetPllFreq(kCLOCK_PllEnet25M); | ||
427 | break; | ||
428 | case kCLOCK_AudioPllClk: | ||
429 | freq = CLOCK_GetPllFreq(kCLOCK_PllAudio); | ||
430 | break; | ||
431 | case kCLOCK_VideoPllClk: | ||
432 | freq = CLOCK_GetPllFreq(kCLOCK_PllVideo); | ||
433 | break; | ||
434 | default: | ||
435 | freq = 0U; | ||
436 | break; | ||
437 | } | ||
438 | |||
439 | return freq; | ||
440 | } | ||
441 | |||
442 | /*! | ||
443 | * brief Gets the frequency of selected clock root. | ||
444 | * | ||
445 | * param clockRoot The clock root used to get the frequency, please refer to @ref clock_root_t. | ||
446 | * return The frequency of selected clock root. | ||
447 | */ | ||
448 | uint32_t CLOCK_GetClockRootFreq(clock_root_t clockRoot) | ||
449 | { | ||
450 | const clock_name_t clockRootSourceArray[][6] = CLOCK_ROOT_SOUCE; | ||
451 | const clock_mux_t clockRootMuxTupleArray[] = CLOCK_ROOT_MUX_TUPLE; | ||
452 | const clock_div_t clockRootDivTupleArray[][2] = CLOCK_ROOT_DIV_TUPLE; | ||
453 | uint32_t freq = 0UL; | ||
454 | clock_mux_t clockRootMuxTuple = clockRootMuxTupleArray[(uint8_t)clockRoot]; | ||
455 | clock_div_t clockRootPreDivTuple = clockRootDivTupleArray[(uint8_t)clockRoot][0]; | ||
456 | clock_div_t clockRootPostDivTuple = clockRootDivTupleArray[(uint8_t)clockRoot][1]; | ||
457 | uint32_t clockRootMuxValue = (CCM_TUPLE_REG(CCM, clockRootMuxTuple) & CCM_TUPLE_MASK(clockRootMuxTuple)) >> | ||
458 | CCM_TUPLE_SHIFT(clockRootMuxTuple); | ||
459 | clock_name_t clockSourceName; | ||
460 | |||
461 | clockSourceName = clockRootSourceArray[(uint8_t)clockRoot][clockRootMuxValue]; | ||
462 | |||
463 | assert(clockSourceName != kCLOCK_NoneName); | ||
464 | |||
465 | freq = CLOCK_GetFreq(clockSourceName); | ||
466 | |||
467 | if (clockRootPreDivTuple != kCLOCK_NonePreDiv) | ||
468 | { | ||
469 | freq /= ((CCM_TUPLE_REG(CCM, clockRootPreDivTuple) & CCM_TUPLE_MASK(clockRootPreDivTuple)) >> | ||
470 | CCM_TUPLE_SHIFT(clockRootPreDivTuple)) + | ||
471 | 1UL; | ||
472 | } | ||
473 | |||
474 | freq /= ((CCM_TUPLE_REG(CCM, clockRootPostDivTuple) & CCM_TUPLE_MASK(clockRootPostDivTuple)) >> | ||
475 | CCM_TUPLE_SHIFT(clockRootPostDivTuple)) + | ||
476 | 1UL; | ||
477 | |||
478 | return freq; | ||
479 | } | ||
480 | |||
481 | /*! brief Enable USB HS clock. | ||
482 | * | ||
483 | * This function only enables the access to USB HS prepheral, upper layer | ||
484 | * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY | ||
485 | * clock to use USB HS. | ||
486 | * | ||
487 | * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused. | ||
488 | * param freq USB HS does not care about the clock source, so this parameter is ignored. | ||
489 | * retval true The clock is set successfully. | ||
490 | * retval false The clock source is invalid to get proper USB HS clock. | ||
491 | */ | ||
492 | bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq) | ||
493 | { | ||
494 | uint32_t i; | ||
495 | CCM->CCGR6 |= CCM_CCGR6_CG0_MASK; | ||
496 | USB1->USBCMD |= USBHS_USBCMD_RST_MASK; | ||
497 | |||
498 | /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/ | ||
499 | for (i = 0; i < 400000U; i++) | ||
500 | { | ||
501 | __ASM("nop"); | ||
502 | } | ||
503 | PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) | | ||
504 | (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK); | ||
505 | return true; | ||
506 | } | ||
507 | |||
508 | /*! brief Enable USB HS clock. | ||
509 | * | ||
510 | * This function only enables the access to USB HS prepheral, upper layer | ||
511 | * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY | ||
512 | * clock to use USB HS. | ||
513 | * | ||
514 | * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused. | ||
515 | * param freq USB HS does not care about the clock source, so this parameter is ignored. | ||
516 | * retval true The clock is set successfully. | ||
517 | * retval false The clock source is invalid to get proper USB HS clock. | ||
518 | */ | ||
519 | bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq) | ||
520 | { | ||
521 | uint32_t i = 0; | ||
522 | CCM->CCGR6 |= CCM_CCGR6_CG0_MASK; | ||
523 | USB2->USBCMD |= USBHS_USBCMD_RST_MASK; | ||
524 | |||
525 | /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/ | ||
526 | for (i = 0; i < 400000U; i++) | ||
527 | { | ||
528 | __ASM("nop"); | ||
529 | } | ||
530 | PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) | | ||
531 | (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK); | ||
532 | return true; | ||
533 | } | ||
534 | |||
535 | /*! brief Enable USB HS PHY PLL clock. | ||
536 | * | ||
537 | * This function enables the internal 480MHz USB PHY PLL clock. | ||
538 | * | ||
539 | * param src USB HS PHY PLL clock source. | ||
540 | * param freq The frequency specified by src. | ||
541 | * retval true The clock is set successfully. | ||
542 | * retval false The clock source is invalid to get proper USB HS clock. | ||
543 | */ | ||
544 | bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq) | ||
545 | { | ||
546 | const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; | ||
547 | if ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_ENABLE_MASK) != 0U) | ||
548 | { | ||
549 | CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; | ||
550 | } | ||
551 | else | ||
552 | { | ||
553 | CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll); | ||
554 | } | ||
555 | USBPHY1->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */ | ||
556 | USBPHY1->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK; | ||
557 | |||
558 | USBPHY1->PWD = 0; | ||
559 | USBPHY1->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | | ||
560 | USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK; | ||
561 | return true; | ||
562 | } | ||
563 | |||
564 | /*! brief Disable USB HS PHY PLL clock. | ||
565 | * | ||
566 | * This function disables USB HS PHY PLL clock. | ||
567 | */ | ||
568 | void CLOCK_DisableUsbhs0PhyPllClock(void) | ||
569 | { | ||
570 | CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; | ||
571 | USBPHY1->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */ | ||
572 | } | ||
573 | |||
574 | /*! | ||
575 | * brief Initialize the ARM PLL. | ||
576 | * | ||
577 | * This function initialize the ARM PLL with specific settings | ||
578 | * | ||
579 | * param config configuration to set to PLL. | ||
580 | */ | ||
581 | void CLOCK_InitArmPll(const clock_arm_pll_config_t *config) | ||
582 | { | ||
583 | /* Bypass PLL first */ | ||
584 | CCM_ANALOG->PLL_ARM = (CCM_ANALOG->PLL_ARM & (~CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_MASK)) | | ||
585 | CCM_ANALOG_PLL_ARM_BYPASS_MASK | CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC(config->src); | ||
586 | |||
587 | CCM_ANALOG->PLL_ARM = | ||
588 | (CCM_ANALOG->PLL_ARM & (~(CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK | CCM_ANALOG_PLL_ARM_POWERDOWN_MASK))) | | ||
589 | CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_DIV_SELECT(config->loopDivider); | ||
590 | |||
591 | while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0UL) | ||
592 | { | ||
593 | } | ||
594 | |||
595 | /* Disable Bypass */ | ||
596 | CCM_ANALOG->PLL_ARM &= ~CCM_ANALOG_PLL_ARM_BYPASS_MASK; | ||
597 | } | ||
598 | |||
599 | /*! | ||
600 | * brief De-initialize the ARM PLL. | ||
601 | */ | ||
602 | void CLOCK_DeinitArmPll(void) | ||
603 | { | ||
604 | CCM_ANALOG->PLL_ARM = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; | ||
605 | } | ||
606 | |||
607 | /*! | ||
608 | * brief Initialize the System PLL. | ||
609 | * | ||
610 | * This function initializes the System PLL with specific settings | ||
611 | * | ||
612 | * param config Configuration to set to PLL. | ||
613 | */ | ||
614 | void CLOCK_InitSysPll(const clock_sys_pll_config_t *config) | ||
615 | { | ||
616 | /* Bypass PLL first */ | ||
617 | CCM_ANALOG->PLL_SYS = (CCM_ANALOG->PLL_SYS & (~CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_MASK)) | | ||
618 | CCM_ANALOG_PLL_SYS_BYPASS_MASK | CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC(config->src); | ||
619 | |||
620 | CCM_ANALOG->PLL_SYS = | ||
621 | (CCM_ANALOG->PLL_SYS & (~(CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK | CCM_ANALOG_PLL_SYS_POWERDOWN_MASK))) | | ||
622 | CCM_ANALOG_PLL_SYS_ENABLE_MASK | CCM_ANALOG_PLL_SYS_DIV_SELECT(config->loopDivider); | ||
623 | |||
624 | /* Initialize the fractional mode */ | ||
625 | CCM_ANALOG->PLL_SYS_NUM = CCM_ANALOG_PLL_SYS_NUM_A(config->numerator); | ||
626 | CCM_ANALOG->PLL_SYS_DENOM = CCM_ANALOG_PLL_SYS_DENOM_B(config->denominator); | ||
627 | |||
628 | /* Initialize the spread spectrum mode */ | ||
629 | CCM_ANALOG->PLL_SYS_SS = CCM_ANALOG_PLL_SYS_SS_STEP(config->ss_step) | | ||
630 | CCM_ANALOG_PLL_SYS_SS_ENABLE(config->ss_enable) | | ||
631 | CCM_ANALOG_PLL_SYS_SS_STOP(config->ss_stop); | ||
632 | |||
633 | while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0UL) | ||
634 | { | ||
635 | } | ||
636 | |||
637 | /* Disable Bypass */ | ||
638 | CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_BYPASS_MASK; | ||
639 | } | ||
640 | |||
641 | /*! | ||
642 | * brief De-initialize the System PLL. | ||
643 | */ | ||
644 | void CLOCK_DeinitSysPll(void) | ||
645 | { | ||
646 | CCM_ANALOG->PLL_SYS = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK; | ||
647 | } | ||
648 | |||
649 | /*! | ||
650 | * brief Initialize the USB1 PLL. | ||
651 | * | ||
652 | * This function initializes the USB1 PLL with specific settings | ||
653 | * | ||
654 | * param config Configuration to set to PLL. | ||
655 | */ | ||
656 | void CLOCK_InitUsb1Pll(const clock_usb_pll_config_t *config) | ||
657 | { | ||
658 | /* Bypass PLL first */ | ||
659 | CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK)) | | ||
660 | CCM_ANALOG_PLL_USB1_BYPASS_MASK | CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC(config->src); | ||
661 | |||
662 | CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK)) | | ||
663 | CCM_ANALOG_PLL_USB1_ENABLE_MASK | CCM_ANALOG_PLL_USB1_POWER_MASK | | ||
664 | CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB1_DIV_SELECT(config->loopDivider); | ||
665 | |||
666 | while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0UL) | ||
667 | { | ||
668 | } | ||
669 | |||
670 | /* Disable Bypass */ | ||
671 | CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK; | ||
672 | } | ||
673 | |||
674 | /*! | ||
675 | * brief Deinitialize the USB1 PLL. | ||
676 | */ | ||
677 | void CLOCK_DeinitUsb1Pll(void) | ||
678 | { | ||
679 | CCM_ANALOG->PLL_USB1 = 0U; | ||
680 | } | ||
681 | |||
682 | /*! | ||
683 | * brief Initialize the USB2 PLL. | ||
684 | * | ||
685 | * This function initializes the USB2 PLL with specific settings | ||
686 | * | ||
687 | * param config Configuration to set to PLL. | ||
688 | */ | ||
689 | void CLOCK_InitUsb2Pll(const clock_usb_pll_config_t *config) | ||
690 | { | ||
691 | /* Bypass PLL first */ | ||
692 | CCM_ANALOG->PLL_USB2 = (CCM_ANALOG->PLL_USB2 & (~CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC_MASK)) | | ||
693 | CCM_ANALOG_PLL_USB2_BYPASS_MASK | CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC(config->src); | ||
694 | |||
695 | CCM_ANALOG->PLL_USB2 = (CCM_ANALOG->PLL_USB2 & (~CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK)) | | ||
696 | CCM_ANALOG_PLL_USB2_ENABLE_MASK | CCM_ANALOG_PLL_USB2_POWER_MASK | | ||
697 | CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB2_DIV_SELECT(config->loopDivider); | ||
698 | |||
699 | while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0UL) | ||
700 | { | ||
701 | } | ||
702 | |||
703 | /* Disable Bypass */ | ||
704 | CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_BYPASS_MASK; | ||
705 | } | ||
706 | |||
707 | /*! | ||
708 | * brief Deinitialize the USB2 PLL. | ||
709 | */ | ||
710 | void CLOCK_DeinitUsb2Pll(void) | ||
711 | { | ||
712 | CCM_ANALOG->PLL_USB2 = 0U; | ||
713 | } | ||
714 | |||
715 | /*! | ||
716 | * brief Initializes the Audio PLL. | ||
717 | * | ||
718 | * This function initializes the Audio PLL with specific settings | ||
719 | * | ||
720 | * param config Configuration to set to PLL. | ||
721 | */ | ||
722 | void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config) | ||
723 | { | ||
724 | uint32_t pllAudio; | ||
725 | uint32_t misc2 = 0; | ||
726 | |||
727 | /* Bypass PLL first */ | ||
728 | CCM_ANALOG->PLL_AUDIO = (CCM_ANALOG->PLL_AUDIO & (~CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC_MASK)) | | ||
729 | CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(config->src); | ||
730 | |||
731 | CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(config->numerator); | ||
732 | CCM_ANALOG->PLL_AUDIO_DENOM = CCM_ANALOG_PLL_AUDIO_DENOM_B(config->denominator); | ||
733 | |||
734 | /* | ||
735 | * Set post divider: | ||
736 | * | ||
737 | * ------------------------------------------------------------------------ | ||
738 | * | config->postDivider | PLL_AUDIO[POST_DIV_SELECT] | MISC2[AUDIO_DIV] | | ||
739 | * ------------------------------------------------------------------------ | ||
740 | * | 1 | 2 | 0 | | ||
741 | * ------------------------------------------------------------------------ | ||
742 | * | 2 | 1 | 0 | | ||
743 | * ------------------------------------------------------------------------ | ||
744 | * | 4 | 2 | 3 | | ||
745 | * ------------------------------------------------------------------------ | ||
746 | * | 8 | 1 | 3 | | ||
747 | * ------------------------------------------------------------------------ | ||
748 | * | 16 | 0 | 3 | | ||
749 | * ------------------------------------------------------------------------ | ||
750 | */ | ||
751 | pllAudio = | ||
752 | (CCM_ANALOG->PLL_AUDIO & (~(CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK | CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK))) | | ||
753 | CCM_ANALOG_PLL_AUDIO_ENABLE_MASK | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(config->loopDivider); | ||
754 | |||
755 | switch (config->postDivider) | ||
756 | { | ||
757 | case 16: | ||
758 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0); | ||
759 | misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; | ||
760 | break; | ||
761 | |||
762 | case 8: | ||
763 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1); | ||
764 | misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; | ||
765 | break; | ||
766 | |||
767 | case 4: | ||
768 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2); | ||
769 | misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; | ||
770 | break; | ||
771 | |||
772 | case 2: | ||
773 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1); | ||
774 | break; | ||
775 | |||
776 | default: | ||
777 | pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2); | ||
778 | break; | ||
779 | } | ||
780 | |||
781 | CCM_ANALOG->MISC2 = | ||
782 | (CCM_ANALOG->MISC2 & ~(CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK)) | misc2; | ||
783 | |||
784 | CCM_ANALOG->PLL_AUDIO = pllAudio; | ||
785 | |||
786 | while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0UL) | ||
787 | { | ||
788 | } | ||
789 | |||
790 | /* Disable Bypass */ | ||
791 | CCM_ANALOG->PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; | ||
792 | } | ||
793 | |||
794 | /*! | ||
795 | * brief De-initialize the Audio PLL. | ||
796 | */ | ||
797 | void CLOCK_DeinitAudioPll(void) | ||
798 | { | ||
799 | CCM_ANALOG->PLL_AUDIO = (uint32_t)CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; | ||
800 | } | ||
801 | |||
802 | /*! | ||
803 | * brief Initialize the video PLL. | ||
804 | * | ||
805 | * This function configures the Video PLL with specific settings | ||
806 | * | ||
807 | * param config configuration to set to PLL. | ||
808 | */ | ||
809 | void CLOCK_InitVideoPll(const clock_video_pll_config_t *config) | ||
810 | { | ||
811 | uint32_t pllVideo; | ||
812 | uint32_t misc2 = 0; | ||
813 | |||
814 | /* Bypass PLL first */ | ||
815 | CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) | | ||
816 | CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(config->src); | ||
817 | |||
818 | CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(config->numerator); | ||
819 | CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(config->denominator); | ||
820 | |||
821 | /* | ||
822 | * Set post divider: | ||
823 | * | ||
824 | * ------------------------------------------------------------------------ | ||
825 | * | config->postDivider | PLL_VIDEO[POST_DIV_SELECT] | MISC2[VIDEO_DIV] | | ||
826 | * ------------------------------------------------------------------------ | ||
827 | * | 1 | 2 | 0 | | ||
828 | * ------------------------------------------------------------------------ | ||
829 | * | 2 | 1 | 0 | | ||
830 | * ------------------------------------------------------------------------ | ||
831 | * | 4 | 2 | 3 | | ||
832 | * ------------------------------------------------------------------------ | ||
833 | * | 8 | 1 | 3 | | ||
834 | * ------------------------------------------------------------------------ | ||
835 | * | 16 | 0 | 3 | | ||
836 | * ------------------------------------------------------------------------ | ||
837 | */ | ||
838 | pllVideo = | ||
839 | (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) | | ||
840 | CCM_ANALOG_PLL_VIDEO_ENABLE_MASK | CCM_ANALOG_PLL_VIDEO_DIV_SELECT(config->loopDivider); | ||
841 | |||
842 | switch (config->postDivider) | ||
843 | { | ||
844 | case 16: | ||
845 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0); | ||
846 | misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); | ||
847 | break; | ||
848 | |||
849 | case 8: | ||
850 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); | ||
851 | misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); | ||
852 | break; | ||
853 | |||
854 | case 4: | ||
855 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2); | ||
856 | misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); | ||
857 | break; | ||
858 | |||
859 | case 2: | ||
860 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); | ||
861 | break; | ||
862 | |||
863 | default: | ||
864 | pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2); | ||
865 | break; | ||
866 | } | ||
867 | |||
868 | CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & ~CCM_ANALOG_MISC2_VIDEO_DIV_MASK) | misc2; | ||
869 | |||
870 | CCM_ANALOG->PLL_VIDEO = pllVideo; | ||
871 | |||
872 | while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0UL) | ||
873 | { | ||
874 | } | ||
875 | |||
876 | /* Disable Bypass */ | ||
877 | CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; | ||
878 | } | ||
879 | |||
880 | /*! | ||
881 | * brief De-initialize the Video PLL. | ||
882 | */ | ||
883 | void CLOCK_DeinitVideoPll(void) | ||
884 | { | ||
885 | CCM_ANALOG->PLL_VIDEO = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; | ||
886 | } | ||
887 | |||
888 | /*! | ||
889 | * brief Initialize the ENET PLL. | ||
890 | * | ||
891 | * This function initializes the ENET PLL with specific settings. | ||
892 | * | ||
893 | * param config Configuration to set to PLL. | ||
894 | */ | ||
895 | void CLOCK_InitEnetPll(const clock_enet_pll_config_t *config) | ||
896 | { | ||
897 | uint32_t enet_pll = CCM_ANALOG_PLL_ENET_DIV_SELECT(config->loopDivider) | | ||
898 | CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT(config->loopDivider1); | ||
899 | |||
900 | CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK)) | | ||
901 | CCM_ANALOG_PLL_ENET_BYPASS_MASK | CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(config->src); | ||
902 | |||
903 | if (config->enableClkOutput) | ||
904 | { | ||
905 | enet_pll |= CCM_ANALOG_PLL_ENET_ENABLE_MASK; | ||
906 | } | ||
907 | |||
908 | if (config->enableClkOutput1) | ||
909 | { | ||
910 | enet_pll |= CCM_ANALOG_PLL_ENET_ENET2_REF_EN_MASK; | ||
911 | } | ||
912 | |||
913 | if (config->enableClkOutput25M) | ||
914 | { | ||
915 | enet_pll |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; | ||
916 | } | ||
917 | |||
918 | CCM_ANALOG->PLL_ENET = | ||
919 | (CCM_ANALOG->PLL_ENET & (~(CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT_MASK | | ||
920 | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK))) | | ||
921 | enet_pll; | ||
922 | |||
923 | /* Wait for stable */ | ||
924 | while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0UL) | ||
925 | { | ||
926 | } | ||
927 | |||
928 | /* Disable Bypass */ | ||
929 | CCM_ANALOG->PLL_ENET &= ~CCM_ANALOG_PLL_ENET_BYPASS_MASK; | ||
930 | } | ||
931 | |||
932 | /*! | ||
933 | * brief Deinitialize the ENET PLL. | ||
934 | * | ||
935 | * This function disables the ENET PLL. | ||
936 | */ | ||
937 | void CLOCK_DeinitEnetPll(void) | ||
938 | { | ||
939 | CCM_ANALOG->PLL_ENET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; | ||
940 | } | ||
941 | |||
942 | /*! | ||
943 | * brief Get current PLL output frequency. | ||
944 | * | ||
945 | * This function get current output frequency of specific PLL | ||
946 | * | ||
947 | * param pll pll name to get frequency. | ||
948 | * return The PLL output frequency in hertz. | ||
949 | */ | ||
950 | uint32_t CLOCK_GetPllFreq(clock_pll_t pll) | ||
951 | { | ||
952 | uint32_t freq; | ||
953 | uint32_t divSelect; | ||
954 | clock_64b_t freqTmp; | ||
955 | |||
956 | const uint32_t enetRefClkFreq[] = { | ||
957 | 25000000U, /* 25M */ | ||
958 | 50000000U, /* 50M */ | ||
959 | 100000000U, /* 100M */ | ||
960 | 125000000U /* 125M */ | ||
961 | }; | ||
962 | |||
963 | /* check if PLL is enabled */ | ||
964 | if (!CLOCK_IsPllEnabled(CCM_ANALOG, pll)) | ||
965 | { | ||
966 | return 0U; | ||
967 | } | ||
968 | |||
969 | /* get pll reference clock */ | ||
970 | freq = CLOCK_GetPllBypassRefClk(CCM_ANALOG, pll); | ||
971 | |||
972 | /* check if pll is bypassed */ | ||
973 | if (CLOCK_IsPllBypassed(CCM_ANALOG, pll)) | ||
974 | { | ||
975 | return freq; | ||
976 | } | ||
977 | |||
978 | switch (pll) | ||
979 | { | ||
980 | case kCLOCK_PllArm: | ||
981 | freq = ((freq * ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >> | ||
982 | CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT)) >> | ||
983 | 1U); | ||
984 | break; | ||
985 | case kCLOCK_PllSys: | ||
986 | /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ | ||
987 | freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_SYS_NUM))); | ||
988 | freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_SYS_DENOM)); | ||
989 | |||
990 | if ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK) != 0U) | ||
991 | { | ||
992 | freq *= 22U; | ||
993 | } | ||
994 | else | ||
995 | { | ||
996 | freq *= 20U; | ||
997 | } | ||
998 | |||
999 | freq += (uint32_t)freqTmp; | ||
1000 | break; | ||
1001 | |||
1002 | case kCLOCK_PllUsb1: | ||
1003 | freq = (freq * (((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) != 0UL) ? 22U : 20U)); | ||
1004 | break; | ||
1005 | |||
1006 | case kCLOCK_PllAudio: | ||
1007 | /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ | ||
1008 | divSelect = | ||
1009 | (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_AUDIO_DIV_SELECT_SHIFT; | ||
1010 | |||
1011 | freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_NUM))); | ||
1012 | freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_DENOM)); | ||
1013 | |||
1014 | freq = freq * divSelect + (uint32_t)freqTmp; | ||
1015 | |||
1016 | /* AUDIO PLL output = PLL output frequency / POSTDIV. */ | ||
1017 | |||
1018 | /* | ||
1019 | * Post divider: | ||
1020 | * | ||
1021 | * PLL_AUDIO[POST_DIV_SELECT]: | ||
1022 | * 0x00: 4 | ||
1023 | * 0x01: 2 | ||
1024 | * 0x02: 1 | ||
1025 | * | ||
1026 | * MISC2[AUDO_DIV]: | ||
1027 | * 0x00: 1 | ||
1028 | * 0x01: 2 | ||
1029 | * 0x02: 1 | ||
1030 | * 0x03: 4 | ||
1031 | */ | ||
1032 | switch (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT_MASK) | ||
1033 | { | ||
1034 | case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0U): | ||
1035 | freq = freq >> 2U; | ||
1036 | break; | ||
1037 | |||
1038 | case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1U): | ||
1039 | freq = freq >> 1U; | ||
1040 | break; | ||
1041 | |||
1042 | case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2U): | ||
1043 | freq = freq >> 0U; | ||
1044 | break; | ||
1045 | |||
1046 | default: | ||
1047 | assert(false); | ||
1048 | break; | ||
1049 | } | ||
1050 | |||
1051 | switch (CCM_ANALOG->MISC2 & (CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK)) | ||
1052 | { | ||
1053 | case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1): | ||
1054 | freq >>= 2U; | ||
1055 | break; | ||
1056 | |||
1057 | case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1): | ||
1058 | freq >>= 1U; | ||
1059 | break; | ||
1060 | |||
1061 | case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0): | ||
1062 | case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0): | ||
1063 | freq >>= 0U; | ||
1064 | break; | ||
1065 | |||
1066 | default: | ||
1067 | assert(false); | ||
1068 | break; | ||
1069 | } | ||
1070 | break; | ||
1071 | |||
1072 | case kCLOCK_PllVideo: | ||
1073 | /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ | ||
1074 | divSelect = | ||
1075 | (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_VIDEO_DIV_SELECT_SHIFT; | ||
1076 | |||
1077 | freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_NUM))); | ||
1078 | freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_DENOM)); | ||
1079 | freq = freq * divSelect + (uint32_t)freqTmp; | ||
1080 | |||
1081 | /* VIDEO PLL output = PLL output frequency / POSTDIV. */ | ||
1082 | |||
1083 | /* | ||
1084 | * Post divider: | ||
1085 | * | ||
1086 | * PLL_VIDEO[POST_DIV_SELECT]: | ||
1087 | * 0x00: 4 | ||
1088 | * 0x01: 2 | ||
1089 | * 0x02: 1 | ||
1090 | * | ||
1091 | * MISC2[VIDEO_DIV]: | ||
1092 | * 0x00: 1 | ||
1093 | * 0x01: 2 | ||
1094 | * 0x02: 1 | ||
1095 | * 0x03: 4 | ||
1096 | */ | ||
1097 | switch (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_MASK) | ||
1098 | { | ||
1099 | case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0U): | ||
1100 | freq = freq >> 2U; | ||
1101 | break; | ||
1102 | |||
1103 | case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1U): | ||
1104 | freq = freq >> 1U; | ||
1105 | break; | ||
1106 | |||
1107 | case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2U): | ||
1108 | freq = freq >> 0U; | ||
1109 | break; | ||
1110 | |||
1111 | default: | ||
1112 | assert(false); | ||
1113 | break; | ||
1114 | } | ||
1115 | |||
1116 | switch (CCM_ANALOG->MISC2 & CCM_ANALOG_MISC2_VIDEO_DIV_MASK) | ||
1117 | { | ||
1118 | case CCM_ANALOG_MISC2_VIDEO_DIV(3U): | ||
1119 | freq >>= 2U; | ||
1120 | break; | ||
1121 | |||
1122 | case CCM_ANALOG_MISC2_VIDEO_DIV(1U): | ||
1123 | freq >>= 1U; | ||
1124 | break; | ||
1125 | |||
1126 | case CCM_ANALOG_MISC2_VIDEO_DIV(0U): | ||
1127 | case CCM_ANALOG_MISC2_VIDEO_DIV(2U): | ||
1128 | freq >>= 0U; | ||
1129 | break; | ||
1130 | |||
1131 | default: | ||
1132 | assert(false); | ||
1133 | break; | ||
1134 | } | ||
1135 | break; | ||
1136 | case kCLOCK_PllEnet: | ||
1137 | divSelect = | ||
1138 | (CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_ENET_DIV_SELECT_SHIFT; | ||
1139 | freq = enetRefClkFreq[divSelect]; | ||
1140 | break; | ||
1141 | |||
1142 | case kCLOCK_PllEnet2: | ||
1143 | divSelect = (CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT_MASK) >> | ||
1144 | CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT_SHIFT; | ||
1145 | freq = enetRefClkFreq[divSelect]; | ||
1146 | break; | ||
1147 | |||
1148 | case kCLOCK_PllEnet25M: | ||
1149 | /* ref_enetpll1 if fixed at 25MHz. */ | ||
1150 | freq = 25000000UL; | ||
1151 | break; | ||
1152 | |||
1153 | case kCLOCK_PllUsb2: | ||
1154 | freq = (freq * (((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0U) ? 22U : 20U)); | ||
1155 | break; | ||
1156 | default: | ||
1157 | freq = 0U; | ||
1158 | break; | ||
1159 | } | ||
1160 | |||
1161 | return freq; | ||
1162 | } | ||
1163 | |||
1164 | /*! | ||
1165 | * brief Initialize the System PLL PFD. | ||
1166 | * | ||
1167 | * This function initializes the System PLL PFD. During new value setting, | ||
1168 | * the clock output is disabled to prevent glitch. | ||
1169 | * | ||
1170 | * param pfd Which PFD clock to enable. | ||
1171 | * param pfdFrac The PFD FRAC value. | ||
1172 | * note It is recommended that PFD settings are kept between 12-35. | ||
1173 | */ | ||
1174 | void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t pfdFrac) | ||
1175 | { | ||
1176 | uint32_t pfdIndex = (uint32_t)pfd; | ||
1177 | uint32_t pfd528; | ||
1178 | |||
1179 | pfd528 = CCM_ANALOG->PFD_528 & | ||
1180 | ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) | ||
1181 | << (8UL * pfdIndex))); | ||
1182 | |||
1183 | /* Disable the clock output first. */ | ||
1184 | CCM_ANALOG->PFD_528 = pfd528 | ((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8UL * pfdIndex)); | ||
1185 | |||
1186 | /* Set the new value and enable output. */ | ||
1187 | CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex)); | ||
1188 | } | ||
1189 | |||
1190 | /*! | ||
1191 | * brief De-initialize the System PLL PFD. | ||
1192 | * | ||
1193 | * This function disables the System PLL PFD. | ||
1194 | * | ||
1195 | * param pfd Which PFD clock to disable. | ||
1196 | */ | ||
1197 | void CLOCK_DeinitSysPfd(clock_pfd_t pfd) | ||
1198 | { | ||
1199 | CCM_ANALOG->PFD_528 |= (uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8U * (uint8_t)pfd); | ||
1200 | } | ||
1201 | |||
1202 | /*! | ||
1203 | * brief Initialize the USB1 PLL PFD. | ||
1204 | * | ||
1205 | * This function initializes the USB1 PLL PFD. During new value setting, | ||
1206 | * the clock output is disabled to prevent glitch. | ||
1207 | * | ||
1208 | * param pfd Which PFD clock to enable. | ||
1209 | * param pfdFrac The PFD FRAC value. | ||
1210 | * note It is recommended that PFD settings are kept between 12-35. | ||
1211 | */ | ||
1212 | void CLOCK_InitUsb1Pfd(clock_pfd_t pfd, uint8_t pfdFrac) | ||
1213 | { | ||
1214 | uint32_t pfdIndex = (uint32_t)pfd; | ||
1215 | uint32_t pfd480; | ||
1216 | |||
1217 | pfd480 = CCM_ANALOG->PFD_480 & | ||
1218 | ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) | ||
1219 | << (8UL * pfdIndex))); | ||
1220 | |||
1221 | /* Disable the clock output first. */ | ||
1222 | CCM_ANALOG->PFD_480 = pfd480 | ((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * pfdIndex)); | ||
1223 | |||
1224 | /* Set the new value and enable output. */ | ||
1225 | CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex)); | ||
1226 | } | ||
1227 | |||
1228 | /*! | ||
1229 | * brief De-initialize the USB1 PLL PFD. | ||
1230 | * | ||
1231 | * This function disables the USB1 PLL PFD. | ||
1232 | * | ||
1233 | * param pfd Which PFD clock to disable. | ||
1234 | */ | ||
1235 | void CLOCK_DeinitUsb1Pfd(clock_pfd_t pfd) | ||
1236 | { | ||
1237 | CCM_ANALOG->PFD_480 |= (uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * (uint8_t)pfd); | ||
1238 | } | ||
1239 | |||
1240 | /*! | ||
1241 | * brief Get current System PLL PFD output frequency. | ||
1242 | * | ||
1243 | * This function get current output frequency of specific System PLL PFD | ||
1244 | * | ||
1245 | * param pfd pfd name to get frequency. | ||
1246 | * return The PFD output frequency in hertz. | ||
1247 | */ | ||
1248 | uint32_t CLOCK_GetSysPfdFreq(clock_pfd_t pfd) | ||
1249 | { | ||
1250 | uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllSys); | ||
1251 | |||
1252 | switch (pfd) | ||
1253 | { | ||
1254 | case kCLOCK_Pfd0: | ||
1255 | freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD0_FRAC_SHIFT); | ||
1256 | break; | ||
1257 | |||
1258 | case kCLOCK_Pfd1: | ||
1259 | freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD1_FRAC_SHIFT); | ||
1260 | break; | ||
1261 | |||
1262 | case kCLOCK_Pfd2: | ||
1263 | freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD2_FRAC_SHIFT); | ||
1264 | break; | ||
1265 | |||
1266 | case kCLOCK_Pfd3: | ||
1267 | freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD3_FRAC_SHIFT); | ||
1268 | break; | ||
1269 | |||
1270 | default: | ||
1271 | freq = 0U; | ||
1272 | break; | ||
1273 | } | ||
1274 | freq *= 18U; | ||
1275 | |||
1276 | return freq; | ||
1277 | } | ||
1278 | |||
1279 | /*! | ||
1280 | * brief Get current USB1 PLL PFD output frequency. | ||
1281 | * | ||
1282 | * This function get current output frequency of specific USB1 PLL PFD | ||
1283 | * | ||
1284 | * param pfd pfd name to get frequency. | ||
1285 | * return The PFD output frequency in hertz. | ||
1286 | */ | ||
1287 | uint32_t CLOCK_GetUsb1PfdFreq(clock_pfd_t pfd) | ||
1288 | { | ||
1289 | uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); | ||
1290 | |||
1291 | switch (pfd) | ||
1292 | { | ||
1293 | case kCLOCK_Pfd0: | ||
1294 | freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); | ||
1295 | break; | ||
1296 | |||
1297 | case kCLOCK_Pfd1: | ||
1298 | freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD1_FRAC_SHIFT); | ||
1299 | break; | ||
1300 | |||
1301 | case kCLOCK_Pfd2: | ||
1302 | freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD2_FRAC_SHIFT); | ||
1303 | break; | ||
1304 | |||
1305 | case kCLOCK_Pfd3: | ||
1306 | freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD3_FRAC_SHIFT); | ||
1307 | break; | ||
1308 | |||
1309 | default: | ||
1310 | freq = 0U; | ||
1311 | break; | ||
1312 | } | ||
1313 | freq *= 18U; | ||
1314 | |||
1315 | return freq; | ||
1316 | } | ||
1317 | |||
1318 | /*! brief Enable USB HS PHY PLL clock. | ||
1319 | * | ||
1320 | * This function enables the internal 480MHz USB PHY PLL clock. | ||
1321 | * | ||
1322 | * param src USB HS PHY PLL clock source. | ||
1323 | * param freq The frequency specified by src. | ||
1324 | * retval true The clock is set successfully. | ||
1325 | * retval false The clock source is invalid to get proper USB HS clock. | ||
1326 | */ | ||
1327 | bool CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src, uint32_t freq) | ||
1328 | { | ||
1329 | const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; | ||
1330 | CLOCK_InitUsb2Pll(&g_ccmConfigUsbPll); | ||
1331 | USBPHY2->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */ | ||
1332 | USBPHY2->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK; | ||
1333 | |||
1334 | USBPHY2->PWD = 0; | ||
1335 | USBPHY2->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | | ||
1336 | USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK; | ||
1337 | |||
1338 | return true; | ||
1339 | } | ||
1340 | |||
1341 | /*! brief Disable USB HS PHY PLL clock. | ||
1342 | * | ||
1343 | * This function disables USB HS PHY PLL clock. | ||
1344 | */ | ||
1345 | void CLOCK_DisableUsbhs1PhyPllClock(void) | ||
1346 | { | ||
1347 | CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK; | ||
1348 | USBPHY2->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */ | ||
1349 | } | ||
1350 | |||
1351 | /*! | ||
1352 | * brief Set the clock source and the divider of the clock output1. | ||
1353 | * | ||
1354 | * param selection The clock source to be output, please refer to clock_output1_selection_t. | ||
1355 | * param divider The divider of the output clock signal, please refer to clock_output_divider_t. | ||
1356 | */ | ||
1357 | void CLOCK_SetClockOutput1(clock_output1_selection_t selection, clock_output_divider_t divider) | ||
1358 | { | ||
1359 | uint32_t tmp32; | ||
1360 | |||
1361 | tmp32 = CCM->CCOSR; | ||
1362 | if (selection == kCLOCK_DisableClockOutput1) | ||
1363 | { | ||
1364 | tmp32 &= ~CCM_CCOSR_CLKO1_EN_MASK; | ||
1365 | } | ||
1366 | else | ||
1367 | { | ||
1368 | tmp32 |= CCM_CCOSR_CLKO1_EN_MASK; | ||
1369 | tmp32 &= ~(CCM_CCOSR_CLKO1_SEL_MASK | CCM_CCOSR_CLKO1_DIV_MASK); | ||
1370 | tmp32 |= CCM_CCOSR_CLKO1_SEL(selection) | CCM_CCOSR_CLKO1_DIV(divider); | ||
1371 | } | ||
1372 | CCM->CCOSR = tmp32; | ||
1373 | } | ||
1374 | |||
1375 | /*! | ||
1376 | * brief Set the clock source and the divider of the clock output2. | ||
1377 | * | ||
1378 | * param selection The clock source to be output, please refer to clock_output2_selection_t. | ||
1379 | * param divider The divider of the output clock signal, please refer to clock_output_divider_t. | ||
1380 | */ | ||
1381 | void CLOCK_SetClockOutput2(clock_output2_selection_t selection, clock_output_divider_t divider) | ||
1382 | { | ||
1383 | uint32_t tmp32; | ||
1384 | |||
1385 | tmp32 = CCM->CCOSR; | ||
1386 | if (selection == kCLOCK_DisableClockOutput2) | ||
1387 | { | ||
1388 | tmp32 &= CCM_CCOSR_CLKO2_EN_MASK; | ||
1389 | } | ||
1390 | else | ||
1391 | { | ||
1392 | tmp32 |= CCM_CCOSR_CLKO2_EN_MASK; | ||
1393 | tmp32 &= ~(CCM_CCOSR_CLKO2_SEL_MASK | CCM_CCOSR_CLKO2_DIV_MASK); | ||
1394 | tmp32 |= CCM_CCOSR_CLKO2_SEL(selection) | CCM_CCOSR_CLKO2_DIV(divider); | ||
1395 | } | ||
1396 | |||
1397 | CCM->CCOSR = tmp32; | ||
1398 | } | ||
1399 | |||
1400 | /*! | ||
1401 | * brief Get the frequency of clock output1 clock signal. | ||
1402 | * | ||
1403 | * return The frequency of clock output1 clock signal. | ||
1404 | */ | ||
1405 | uint32_t CLOCK_GetClockOutCLKO1Freq(void) | ||
1406 | { | ||
1407 | uint32_t freq = 0U; | ||
1408 | uint32_t tmp32; | ||
1409 | |||
1410 | tmp32 = CCM->CCOSR; | ||
1411 | |||
1412 | if ((tmp32 & CCM_CCOSR_CLKO1_EN_MASK) != 0UL) | ||
1413 | { | ||
1414 | switch ((tmp32 & CCM_CCOSR_CLKO1_SEL_MASK) >> CCM_CCOSR_CLKO1_SEL_SHIFT) | ||
1415 | { | ||
1416 | case (uint32_t)kCLOCK_OutputPllUsb1: | ||
1417 | freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 2U; | ||
1418 | break; | ||
1419 | case (uint32_t)kCLOCK_OutputPllSys: | ||
1420 | freq = CLOCK_GetPllFreq(kCLOCK_PllSys) / 2U; | ||
1421 | break; | ||
1422 | case (uint32_t)kCLOCK_OutputPllVideo: | ||
1423 | freq = CLOCK_GetPllFreq(kCLOCK_PllVideo) / 2U; | ||
1424 | break; | ||
1425 | case (uint32_t)kCLOCK_OutputSemcClk: | ||
1426 | freq = CLOCK_GetSemcFreq(); | ||
1427 | break; | ||
1428 | case (uint32_t)kCLOCK_OutputLcdifPixClk: | ||
1429 | freq = CLOCK_GetClockRootFreq(kCLOCK_LcdifClkRoot); | ||
1430 | break; | ||
1431 | case (uint32_t)kCLOCK_OutputAhbClk: | ||
1432 | freq = CLOCK_GetAhbFreq(); | ||
1433 | break; | ||
1434 | case (uint32_t)kCLOCK_OutputIpgClk: | ||
1435 | freq = CLOCK_GetIpgFreq(); | ||
1436 | break; | ||
1437 | case (uint32_t)kCLOCK_OutputPerClk: | ||
1438 | freq = CLOCK_GetPerClkFreq(); | ||
1439 | break; | ||
1440 | case (uint32_t)kCLOCK_OutputCkilSyncClk: | ||
1441 | freq = CLOCK_GetRtcFreq(); | ||
1442 | break; | ||
1443 | case (uint32_t)kCLOCK_OutputPll4MainClk: | ||
1444 | freq = CLOCK_GetPllFreq(kCLOCK_PllAudio); | ||
1445 | break; | ||
1446 | default: | ||
1447 | /* This branch should never be hit. */ | ||
1448 | break; | ||
1449 | } | ||
1450 | |||
1451 | freq /= (((tmp32 & CCM_CCOSR_CLKO1_DIV_MASK) >> CCM_CCOSR_CLKO1_DIV_SHIFT) + 1U); | ||
1452 | } | ||
1453 | else | ||
1454 | { | ||
1455 | freq = 0UL; | ||
1456 | } | ||
1457 | |||
1458 | return freq; | ||
1459 | } | ||
1460 | |||
1461 | /*! | ||
1462 | * brief Get the frequency of clock output2 clock signal. | ||
1463 | * | ||
1464 | * return The frequency of clock output2 clock signal. | ||
1465 | */ | ||
1466 | uint32_t CLOCK_GetClockOutClkO2Freq(void) | ||
1467 | { | ||
1468 | uint32_t freq = 0U; | ||
1469 | uint32_t tmp32; | ||
1470 | |||
1471 | tmp32 = CCM->CCOSR; | ||
1472 | |||
1473 | if ((tmp32 & CCM_CCOSR_CLKO2_EN_MASK) != 0UL) | ||
1474 | { | ||
1475 | switch ((tmp32 & CCM_CCOSR_CLKO2_SEL_MASK) >> CCM_CCOSR_CLKO2_SEL_SHIFT) | ||
1476 | { | ||
1477 | case (uint32_t)kCLOCK_OutputUsdhc1Clk: | ||
1478 | freq = CLOCK_GetClockRootFreq(kCLOCK_Usdhc1ClkRoot); | ||
1479 | break; | ||
1480 | case (uint32_t)kCLOCK_OutputLpi2cClk: | ||
1481 | freq = CLOCK_GetClockRootFreq(kCLOCK_Lpi2cClkRoot); | ||
1482 | break; | ||
1483 | case (uint32_t)kCLOCK_OutputCsiClk: | ||
1484 | freq = CLOCK_GetClockRootFreq(kCLOCK_CsiClkRoot); | ||
1485 | break; | ||
1486 | case (uint32_t)kCLOCK_OutputOscClk: | ||
1487 | freq = CLOCK_GetOscFreq(); | ||
1488 | break; | ||
1489 | case (uint32_t)kCLOCK_OutputUsdhc2Clk: | ||
1490 | freq = CLOCK_GetClockRootFreq(kCLOCK_Usdhc2ClkRoot); | ||
1491 | break; | ||
1492 | case (uint32_t)kCLOCK_OutputSai1Clk: | ||
1493 | freq = CLOCK_GetClockRootFreq(kCLOCK_Sai1ClkRoot); | ||
1494 | break; | ||
1495 | case (uint32_t)kCLOCK_OutputSai2Clk: | ||
1496 | freq = CLOCK_GetClockRootFreq(kCLOCK_Sai2ClkRoot); | ||
1497 | break; | ||
1498 | case (uint32_t)kCLOCK_OutputSai3Clk: | ||
1499 | freq = CLOCK_GetClockRootFreq(kCLOCK_Sai3ClkRoot); | ||
1500 | break; | ||
1501 | case (uint32_t)kCLOCK_OutputCanClk: | ||
1502 | freq = CLOCK_GetClockRootFreq(kCLOCK_CanClkRoot); | ||
1503 | break; | ||
1504 | case (uint32_t)kCLOCK_OutputFlexspiClk: | ||
1505 | freq = CLOCK_GetClockRootFreq(kCLOCK_FlexspiClkRoot); | ||
1506 | break; | ||
1507 | case (uint32_t)kCLOCK_OutputUartClk: | ||
1508 | freq = CLOCK_GetClockRootFreq(kCLOCK_UartClkRoot); | ||
1509 | break; | ||
1510 | case (uint32_t)kCLOCK_OutputSpdif0Clk: | ||
1511 | freq = CLOCK_GetClockRootFreq(kCLOCK_SpdifClkRoot); | ||
1512 | break; | ||
1513 | default: | ||
1514 | /* This branch should never be hit. */ | ||
1515 | break; | ||
1516 | } | ||
1517 | |||
1518 | freq /= (((tmp32 & CCM_CCOSR_CLKO2_DIV_MASK) >> CCM_CCOSR_CLKO2_DIV_SHIFT) + 1U); | ||
1519 | } | ||
1520 | else | ||
1521 | { | ||
1522 | freq = 0UL; | ||
1523 | } | ||
1524 | |||
1525 | return freq; | ||
1526 | } | ||