1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_clock.h"
10 #include "fsl_common.h"
11 
12 /*******************************************************************************
13  * Definitions
14  ******************************************************************************/
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.clock"
18 #endif
19 
20 #define OTP_INIT_API      ((void (*)(uint32_t src_clk_freq))0x13007FFF)
21 #define OTP_DEINIT_API    ((void (*)(void))0x1300804D)
22 #define OTP_FUSE_READ_API ((void (*)(uint32_t addr, uint32_t * data))0x1300805D)
23 /* OTP fuse index. */
24 #define FRO_192MHZ_SC_TRIM 0x2C
25 #define FRO_192MHZ_RD_TRIM 0x2B
26 #define FRO_96MHZ_SC_TRIM  0x2E
27 #define FRO_96MHZ_RD_TRIM  0x2D
28 
29 /*******************************************************************************
30  * Variables
31  ******************************************************************************/
32 
33 /* External XTAL (OSC) clock frequency. */
34 volatile uint32_t g_xtalFreq = 0U;
35 /* External CLK_IN pin clock frequency. */
36 volatile uint32_t g_clkinFreq = 0U;
37 /* External MCLK IN clock frequency. */
38 volatile uint32_t g_mclkFreq = 0U;
39 
40 /*******************************************************************************
41  * Code
42  ******************************************************************************/
43 
44 /* Clock Selection for IP */
45 /**
46  * brief   Configure the clock selection muxes.
47  * param   connection : Clock to be configured.
48  * return  Nothing
49  */
CLOCK_AttachClk(clock_attach_id_t connection)50 void CLOCK_AttachClk(clock_attach_id_t connection)
51 {
52     bool final_descriptor = false;
53     uint32_t i;
54     uint32_t tuple;
55     volatile uint32_t *pClkSel;
56 
57     for (i = 0U; (i < 2U) && (!final_descriptor); i++)
58     {
59         tuple = ((uint32_t)connection) >> (i * 14U); /*!<  pick up next descriptor */
60         if ((((uint32_t)connection) & 0x80000000U) != 0UL)
61         {
62             pClkSel = CLKCTL_TUPLE_REG(CLKCTL1, tuple);
63         }
64         else
65         {
66             pClkSel = CLKCTL_TUPLE_REG(CLKCTL0, tuple);
67         }
68         if ((tuple & 0x7FFU) != 0U)
69         {
70             *pClkSel = CLKCTL_TUPLE_SEL(tuple);
71         }
72         else
73         {
74             final_descriptor = true;
75         }
76     }
77 
78     if ((((uint32_t)connection) & 0x40000000U) != 0U)
79     {
80         CLKCTL0->FRODIVSEL = (((uint32_t)connection) >> 28U) & 0x3U;
81     }
82 }
83 
84 /* Set IP Clock divider */
85 /**
86  * brief   Setup peripheral clock dividers.
87  * param   div_name    : Clock divider name
88  * param   divider     : Value to be divided. Divided clock frequency = Undivided clock frequency / divider.
89  * return  Nothing
90  */
CLOCK_SetClkDiv(clock_div_name_t div_name,uint32_t divider)91 void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divider)
92 {
93     volatile uint32_t *pClkDiv;
94 
95     if ((((uint32_t)div_name) & 0x80000000U) != 0U)
96     {
97         pClkDiv = CLKCTL_TUPLE_REG(CLKCTL1, div_name);
98     }
99     else
100     {
101         pClkDiv = CLKCTL_TUPLE_REG(CLKCTL0, div_name);
102     }
103     /* Reset the divider counter */
104     *pClkDiv |= 1UL << 29U;
105 
106     if (divider == 0U) /*!<  halt */
107     {
108         *pClkDiv |= 1UL << 30U;
109     }
110     else
111     {
112         *pClkDiv = divider - 1U;
113 
114         while (((*pClkDiv) & 0x80000000U) != 0U)
115         {
116         }
117     }
118 }
119 
120 /* Get SYSTEM PLL Clk */
121 /*! brief  Return Frequency of SYSPLL
122  *  return Frequency of SYSPLL
123  */
CLOCK_GetSysPllFreq(void)124 uint32_t CLOCK_GetSysPllFreq(void)
125 {
126     uint32_t freq = 0U;
127     uint64_t freqTmp;
128 
129     switch ((CLKCTL0->SYSPLL0CLKSEL) & CLKCTL0_SYSPLL0CLKSEL_SEL_MASK)
130     {
131         case CLKCTL0_SYSPLL0CLKSEL_SEL(0):
132             freq = CLK_FRO_DIV8_CLK;
133             break;
134         case CLKCTL0_SYSPLL0CLKSEL_SEL(1):
135             freq = CLOCK_GetXtalInClkFreq();
136             break;
137         default:
138             assert(false);
139             break;
140     }
141 
142     if (((CLKCTL0->SYSPLL0CTL0) & CLKCTL0_SYSPLL0CTL0_BYPASS_MASK) == 0U)
143     {
144         /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
145         freqTmp = ((uint64_t)freq * ((uint64_t)(CLKCTL0->SYSPLL0NUM))) / ((uint64_t)(CLKCTL0->SYSPLL0DENOM));
146         freq *= ((CLKCTL0->SYSPLL0CTL0) & CLKCTL0_SYSPLL0CTL0_MULT_MASK) >> CLKCTL0_SYSPLL0CTL0_MULT_SHIFT;
147         freq += (uint32_t)freqTmp;
148     }
149 
150     return freq;
151 }
152 
153 /* Get SYSTEM PLL PFDn Clk */
154 /*! brief  Get current output frequency of specific System PLL PFD.
155  *  param   pfd    : pfd name to get frequency.
156  *  return  Frequency of SYSPLL PFD.
157  */
CLOCK_GetSysPfdFreq(clock_pfd_t pfd)158 uint32_t CLOCK_GetSysPfdFreq(clock_pfd_t pfd)
159 {
160     uint32_t freq = CLOCK_GetSysPllFreq();
161 
162     if (((CLKCTL0->SYSPLL0CTL0) & CLKCTL0_SYSPLL0CTL0_BYPASS_MASK) == 0U)
163     {
164         switch (pfd)
165         {
166             case kCLOCK_Pfd0:
167                 freq =
168                     (uint32_t)((uint64_t)freq * 18U /
169                                ((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD0_MASK) >> CLKCTL0_SYSPLL0PFD_PFD0_SHIFT));
170                 break;
171 
172             case kCLOCK_Pfd1:
173                 freq =
174                     (uint32_t)((uint64_t)freq * 18U /
175                                ((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD1_MASK) >> CLKCTL0_SYSPLL0PFD_PFD1_SHIFT));
176                 break;
177 
178             case kCLOCK_Pfd2:
179                 freq =
180                     (uint32_t)((uint64_t)freq * 18U /
181                                ((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD2_MASK) >> CLKCTL0_SYSPLL0PFD_PFD2_SHIFT));
182                 break;
183 
184             case kCLOCK_Pfd3:
185                 freq =
186                     (uint32_t)((uint64_t)freq * 18U /
187                                ((CLKCTL0->SYSPLL0PFD & CLKCTL0_SYSPLL0PFD_PFD3_MASK) >> CLKCTL0_SYSPLL0PFD_PFD3_SHIFT));
188                 break;
189 
190             default:
191                 freq = 0U;
192                 break;
193         }
194     }
195 
196     return freq;
197 }
198 
CLOCK_GetMainPllClkFreq(void)199 static uint32_t CLOCK_GetMainPllClkFreq(void)
200 {
201     return CLOCK_GetSysPfdFreq(kCLOCK_Pfd0) / ((CLKCTL0->MAINPLLCLKDIV & CLKCTL0_MAINPLLCLKDIV_DIV_MASK) + 1U);
202 }
CLOCK_GetDspPllClkFreq(void)203 static uint32_t CLOCK_GetDspPllClkFreq(void)
204 {
205     return CLOCK_GetSysPfdFreq(kCLOCK_Pfd1) / ((CLKCTL0->DSPPLLCLKDIV & CLKCTL0_DSPPLLCLKDIV_DIV_MASK) + 1U);
206 }
CLOCK_GetAux0PllClkFreq(void)207 static uint32_t CLOCK_GetAux0PllClkFreq(void)
208 {
209     return CLOCK_GetSysPfdFreq(kCLOCK_Pfd2) / ((CLKCTL0->AUX0PLLCLKDIV & CLKCTL0_AUX0PLLCLKDIV_DIV_MASK) + 1U);
210 }
CLOCK_GetAux1PllClkFreq(void)211 static uint32_t CLOCK_GetAux1PllClkFreq(void)
212 {
213     return CLOCK_GetSysPfdFreq(kCLOCK_Pfd3) / ((CLKCTL0->AUX1PLLCLKDIV & CLKCTL0_AUX1PLLCLKDIV_DIV_MASK) + 1U);
214 }
215 
216 /* Get AUDIO PLL Clk */
217 /*! brief  Return Frequency of AUDIO PLL
218  *  return Frequency of AUDIO PLL
219  */
CLOCK_GetAudioPllFreq(void)220 uint32_t CLOCK_GetAudioPllFreq(void)
221 {
222     uint32_t freq = 0U;
223     uint64_t freqTmp;
224 
225     switch ((CLKCTL1->AUDIOPLL0CLKSEL) & CLKCTL1_AUDIOPLL0CLKSEL_SEL_MASK)
226     {
227         case CLKCTL1_AUDIOPLL0CLKSEL_SEL(0):
228             freq = CLK_FRO_DIV8_CLK;
229             break;
230         case CLKCTL1_AUDIOPLL0CLKSEL_SEL(1):
231             freq = CLOCK_GetXtalInClkFreq();
232             break;
233         default:
234             freq = 0U;
235             break;
236     }
237 
238     if (((CLKCTL1->AUDIOPLL0CTL0) & CLKCTL1_AUDIOPLL0CTL0_BYPASS_MASK) == 0U)
239     {
240         /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
241         freqTmp = ((uint64_t)freq * ((uint64_t)(CLKCTL1->AUDIOPLL0NUM))) / ((uint64_t)(CLKCTL1->AUDIOPLL0DENOM));
242         freq *= ((CLKCTL1->AUDIOPLL0CTL0) & CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) >> CLKCTL1_AUDIOPLL0CTL0_MULT_SHIFT;
243         freq += (uint32_t)freqTmp;
244     }
245 
246     return freq;
247 }
248 
249 /* Get AUDIO PLL PFDn Clk */
250 /*! brief  Get current output frequency of specific Audio PLL PFD.
251  *  param   pfd    : pfd name to get frequency.
252  *  return  Frequency of AUDIO PLL PFD.
253  */
CLOCK_GetAudioPfdFreq(clock_pfd_t pfd)254 uint32_t CLOCK_GetAudioPfdFreq(clock_pfd_t pfd)
255 {
256     uint32_t freq = CLOCK_GetAudioPllFreq();
257 
258     if (((CLKCTL1->AUDIOPLL0CTL0) & CLKCTL1_AUDIOPLL0CTL0_BYPASS_MASK) == 0U)
259     {
260         switch (pfd)
261         {
262             case kCLOCK_Pfd0:
263                 freq = (uint32_t)(
264                     (uint64_t)freq * 18U /
265                     ((CLKCTL1->AUDIOPLL0PFD & CLKCTL1_AUDIOPLL0PFD_PFD0_MASK) >> CLKCTL1_AUDIOPLL0PFD_PFD0_SHIFT));
266                 break;
267 
268             case kCLOCK_Pfd1:
269                 freq = (uint32_t)(
270                     (uint64_t)freq * 18U /
271                     ((CLKCTL1->AUDIOPLL0PFD & CLKCTL1_AUDIOPLL0PFD_PFD1_MASK) >> CLKCTL1_AUDIOPLL0PFD_PFD1_SHIFT));
272                 break;
273 
274             case kCLOCK_Pfd2:
275                 freq = (uint32_t)(
276                     (uint64_t)freq * 18U /
277                     ((CLKCTL1->AUDIOPLL0PFD & CLKCTL1_AUDIOPLL0PFD_PFD2_MASK) >> CLKCTL1_AUDIOPLL0PFD_PFD2_SHIFT));
278                 break;
279 
280             case kCLOCK_Pfd3:
281                 freq = (uint32_t)(
282                     (uint64_t)freq * 18U /
283                     ((CLKCTL1->AUDIOPLL0PFD & CLKCTL1_AUDIOPLL0PFD_PFD3_MASK) >> CLKCTL1_AUDIOPLL0PFD_PFD3_SHIFT));
284                 break;
285 
286             default:
287                 freq = 0U;
288                 break;
289         }
290     }
291 
292     return freq;
293 }
294 
CLOCK_GetAudioPllClkFreq(void)295 static uint32_t CLOCK_GetAudioPllClkFreq(void)
296 {
297     return CLOCK_GetAudioPfdFreq(kCLOCK_Pfd0) / ((CLKCTL1->AUDIOPLLCLKDIV & CLKCTL1_AUDIOPLLCLKDIV_DIV_MASK) + 1U);
298 }
299 
CLOCK_GetFroDivFreq(void)300 static uint32_t CLOCK_GetFroDivFreq(void)
301 {
302     uint32_t freq = 0U;
303 
304     switch ((CLKCTL0->FRODIVSEL) & CLKCTL0_FRODIVSEL_SEL_MASK)
305     {
306         case CLKCTL0_FRODIVSEL_SEL(0):
307             freq = CLK_FRO_DIV2_CLK;
308             break;
309         case CLKCTL0_FRODIVSEL_SEL(1):
310             freq = CLK_FRO_DIV4_CLK;
311             break;
312         case CLKCTL0_FRODIVSEL_SEL(2):
313             freq = CLK_FRO_DIV8_CLK;
314             break;
315         case CLKCTL0_FRODIVSEL_SEL(3):
316             freq = CLK_FRO_DIV16_CLK;
317             break;
318         default:
319             freq = 0U;
320             break;
321     }
322 
323     return freq;
324 }
325 
326 /* Get MAIN Clk */
327 /*! brief  Return Frequency of main clk
328  *  return Frequency of main clk
329  */
CLOCK_GetMainClkFreq(void)330 uint32_t CLOCK_GetMainClkFreq(void)
331 {
332     uint32_t freq = 0U;
333 
334     switch ((CLKCTL0->MAINCLKSELB) & CLKCTL0_MAINCLKSELB_SEL_MASK)
335     {
336         case CLKCTL0_MAINCLKSELB_SEL(0):
337             switch ((CLKCTL0->MAINCLKSELA) & CLKCTL0_MAINCLKSELA_SEL_MASK)
338             {
339                 case CLKCTL0_MAINCLKSELA_SEL(0):
340                     freq = CLOCK_GetLpOscFreq();
341                     break;
342                 case CLKCTL0_MAINCLKSELA_SEL(1):
343                     freq = CLOCK_GetFroDivFreq();
344                     break;
345                 case CLKCTL0_MAINCLKSELA_SEL(2):
346                     freq = CLOCK_GetXtalInClkFreq();
347                     break;
348                 case CLKCTL0_MAINCLKSELA_SEL(3):
349                     freq = CLK_FRO_CLK;
350                     break;
351                 default:
352                     freq = 0U;
353                     break;
354             }
355             break;
356 
357         case CLKCTL0_MAINCLKSELB_SEL(1):
358             freq = CLOCK_GetMainPllClkFreq();
359             break;
360 
361         case CLKCTL0_MAINCLKSELB_SEL(2):
362             freq = CLOCK_GetOsc32KFreq();
363             break;
364 
365         default:
366             freq = 0U;
367             break;
368     }
369 
370     return freq;
371 }
372 
373 /* Get DSP MAIN Clk */
374 /*! brief  Return Frequency of DSP main clk
375  *  return Frequency of DSP main clk
376  */
CLOCK_GetDspMainClkFreq(void)377 uint32_t CLOCK_GetDspMainClkFreq(void)
378 {
379     uint32_t freq = 0U;
380 
381     switch ((CLKCTL1->DSPCPUCLKSELB) & CLKCTL1_DSPCPUCLKSELB_SEL_MASK)
382     {
383         case CLKCTL1_DSPCPUCLKSELB_SEL(0):
384             switch ((CLKCTL1->DSPCPUCLKSELA) & CLKCTL1_DSPCPUCLKSELA_SEL_MASK)
385             {
386                 case CLKCTL1_DSPCPUCLKSELA_SEL(0):
387                     freq = CLK_FRO_CLK;
388                     break;
389                 case CLKCTL1_DSPCPUCLKSELA_SEL(1):
390                     freq = CLOCK_GetXtalInClkFreq();
391                     break;
392                 case CLKCTL1_DSPCPUCLKSELA_SEL(2):
393                     freq = CLOCK_GetLpOscFreq();
394                     break;
395                 default:
396                     freq = 0U;
397                     break;
398             }
399             break;
400 
401         case CLKCTL1_DSPCPUCLKSELB_SEL(1):
402             freq = CLOCK_GetMainPllClkFreq();
403             break;
404 
405         case CLKCTL1_DSPCPUCLKSELB_SEL(2):
406             freq = CLOCK_GetDspPllClkFreq();
407             break;
408 
409         case CLKCTL1_DSPCPUCLKSELB_SEL(3):
410             freq = CLOCK_GetOsc32KFreq();
411             break;
412 
413         default:
414             freq = 0U;
415             break;
416     }
417 
418     return freq;
419 }
420 
421 /* Get ADC Clk */
422 /*! brief  Return Frequency of Adc Clock
423  *  return Frequency of Adc Clock.
424  */
CLOCK_GetAdcClkFreq(void)425 uint32_t CLOCK_GetAdcClkFreq(void)
426 {
427     uint32_t freq = 0U;
428 
429     switch ((CLKCTL0->ADC0FCLKSEL1) & CLKCTL0_ADC0FCLKSEL1_SEL_MASK)
430     {
431         case CLKCTL0_ADC0FCLKSEL1_SEL(0):
432             switch ((CLKCTL0->ADC0FCLKSEL0) & CLKCTL0_ADC0FCLKSEL0_SEL_MASK)
433             {
434                 case CLKCTL0_ADC0FCLKSEL0_SEL(0):
435                     freq = CLOCK_GetXtalInClkFreq();
436                     break;
437                 case CLKCTL0_ADC0FCLKSEL0_SEL(1):
438                     freq = CLOCK_GetLpOscFreq();
439                     break;
440                 case CLKCTL0_ADC0FCLKSEL0_SEL(2):
441                     freq = CLK_FRO_DIV4_CLK;
442                     break;
443                 default:
444                     freq = 0U;
445                     break;
446             }
447             break;
448 
449         case CLKCTL0_ADC0FCLKSEL1_SEL(1):
450             freq = CLOCK_GetMainPllClkFreq();
451             break;
452 
453         case CLKCTL0_ADC0FCLKSEL1_SEL(2):
454             freq = CLOCK_GetAux0PllClkFreq();
455             break;
456 
457         case CLKCTL0_ADC0FCLKSEL1_SEL(3):
458             freq = CLOCK_GetAux1PllClkFreq();
459             break;
460 
461         default:
462             freq = 0U;
463             break;
464     }
465 
466     return freq / ((CLKCTL0->ADC0FCLKDIV & CLKCTL0_ADC0FCLKDIV_DIV_MASK) + 1U);
467 }
468 
469 /* Get CLOCK OUT Clk */
470 /*! brief  Return Frequency of ClockOut
471  *  return Frequency of ClockOut
472  */
CLOCK_GetClockOutClkFreq(void)473 uint32_t CLOCK_GetClockOutClkFreq(void)
474 {
475     uint32_t freq = 0U;
476 
477     switch ((CLKCTL1->CLKOUTSEL1) & CLKCTL1_CLKOUTSEL1_SEL_MASK)
478     {
479         case CLKCTL1_CLKOUTSEL1_SEL(0):
480             switch ((CLKCTL1->CLKOUTSEL0) & CLKCTL1_CLKOUTSEL0_SEL_MASK)
481             {
482                 case CLKCTL1_CLKOUTSEL0_SEL(0):
483                     freq = CLOCK_GetXtalInClkFreq();
484                     break;
485                 case CLKCTL1_CLKOUTSEL0_SEL(1):
486                     freq = CLOCK_GetLpOscFreq();
487                     break;
488                 case CLKCTL1_CLKOUTSEL0_SEL(2):
489                     freq = CLK_FRO_DIV2_CLK;
490                     break;
491                 case CLKCTL1_CLKOUTSEL0_SEL(3):
492                     freq = CLOCK_GetMainClkFreq();
493                     break;
494                 case CLKCTL1_CLKOUTSEL0_SEL(4):
495                     freq = CLOCK_GetDspMainClkFreq();
496                     break;
497                 default:
498                     freq = 0U;
499                     break;
500             }
501             break;
502 
503         case CLKCTL1_CLKOUTSEL1_SEL(1):
504             freq = CLOCK_GetMainPllClkFreq();
505             break;
506 
507         case CLKCTL1_CLKOUTSEL1_SEL(2):
508             freq = CLOCK_GetAux0PllClkFreq();
509             break;
510 
511         case CLKCTL1_CLKOUTSEL1_SEL(3):
512             freq = CLOCK_GetDspPllClkFreq();
513             break;
514 
515         case CLKCTL1_CLKOUTSEL1_SEL(4):
516             freq = CLOCK_GetAux1PllClkFreq();
517             break;
518 
519         case CLKCTL1_CLKOUTSEL1_SEL(5):
520             freq = CLOCK_GetAudioPllClkFreq();
521             break;
522 
523         case CLKCTL1_CLKOUTSEL1_SEL(6):
524             freq = CLOCK_GetOsc32KFreq();
525             break;
526 
527         default:
528             freq = 0U;
529             break;
530     }
531 
532     return freq / ((CLKCTL1->CLKOUTFCLKDIV & CLKCTL1_CLKOUTFCLKDIV_DIV_MASK) + 1U);
533 }
534 
535 /* Get FRG Clk */
536 /*! brief  Return Input frequency for the Fractional baud rate generator
537  *  return Input Frequency for FRG
538  */
CLOCK_GetFRGClock(uint32_t id)539 uint32_t CLOCK_GetFRGClock(uint32_t id)
540 {
541     uint32_t freq      = 0U;
542     uint32_t frgPllDiv = 1U;
543     uint32_t clkSel    = 0U;
544     uint32_t frgDiv    = 0U;
545     uint32_t frgMul    = 0U;
546 
547     assert(id <= 17U);
548 
549     if (id == 17U)
550     {
551         clkSel = CLKCTL1->FRG17CLKSEL & CLKCTL1_FRG17CLKSEL_SEL_MASK;
552         frgMul = (CLKCTL1->FRG17CTL & CLKCTL1_FRG17CTL_MULT_MASK) >> CLKCTL1_FRG17CTL_MULT_SHIFT;
553         frgDiv = (CLKCTL1->FRG17CTL & CLKCTL1_FRG17CTL_DIV_MASK) >> CLKCTL1_FRG17CTL_DIV_SHIFT;
554     }
555     else
556     {
557         clkSel = CLKCTL1->FLEXCOMM[id].FRGCLKSEL & CLKCTL1_FRGCLKSEL_SEL_MASK;
558         frgMul = (CLKCTL1->FLEXCOMM[id].FRGCTL & CLKCTL1_FRGCTL_MULT_MASK) >> CLKCTL1_FRGCTL_MULT_SHIFT;
559         frgDiv = (CLKCTL1->FLEXCOMM[id].FRGCTL & CLKCTL1_FRGCTL_DIV_MASK) >> CLKCTL1_FRGCTL_DIV_SHIFT;
560     }
561 
562     switch (clkSel)
563     {
564         case CLKCTL1_FRGCLKSEL_SEL(0):
565             freq = CLOCK_GetMainClkFreq();
566             break;
567 
568         case CLKCTL1_FRGCLKSEL_SEL(1):
569             frgPllDiv = (CLKCTL1->FRGPLLCLKDIV & CLKCTL1_FRGPLLCLKDIV_DIV_MASK) + 1U;
570             freq      = CLOCK_GetMainPllClkFreq() / frgPllDiv;
571             break;
572 
573         case CLKCTL1_FRGCLKSEL_SEL(2):
574             freq = CLK_FRO_DIV4_CLK;
575             break;
576 
577         default:
578             freq = 0U;
579             break;
580     }
581 
582     return (uint32_t)(((uint64_t)freq * ((uint64_t)frgDiv + 1ULL)) / (frgMul + frgDiv + 1UL));
583 }
584 
585 /* Get FLEXCOMM Clk */
586 /*! brief  Return Frequency of Flexcomm functional Clock
587  *  param   id    : flexcomm index to get frequency.
588  *  return Frequency of Flexcomm functional Clock
589  */
CLOCK_GetFlexcommClkFreq(uint32_t id)590 uint32_t CLOCK_GetFlexcommClkFreq(uint32_t id)
591 {
592     uint32_t freq   = 0U;
593     uint32_t clkSel = 0U;
594 
595     assert(id <= 16U);
596 
597     clkSel = CLKCTL1->FLEXCOMM[id].FCFCLKSEL;
598 
599     switch (clkSel & CLKCTL1_FCFCLKSEL_SEL_MASK)
600     {
601         case CLKCTL1_FCFCLKSEL_SEL(0):
602             freq = CLK_FRO_DIV4_CLK;
603             break;
604 
605         case CLKCTL1_FCFCLKSEL_SEL(1):
606             freq = CLOCK_GetAudioPllClkFreq();
607             break;
608 
609         case CLKCTL1_FCFCLKSEL_SEL(2):
610             freq = g_mclkFreq;
611             break;
612 
613         case CLKCTL1_FCFCLKSEL_SEL(3):
614             freq = CLOCK_GetFRGClock(id);
615             break;
616 
617         default:
618             freq = 0U;
619             break;
620     }
621 
622     return freq;
623 }
624 
625 /*! @brief  Return Frequency of Flexio functional Clock
626  *  @return Frequency of Flexcomm functional Clock
627  */
CLOCK_GetFlexioClkFreq(void)628 uint32_t CLOCK_GetFlexioClkFreq(void)
629 {
630     uint32_t freq = 0U;
631 
632     switch (CLKCTL1->FLEXIOCLKSEL & CLKCTL1_FLEXIOCLKSEL_SEL_MASK)
633     {
634         case CLKCTL1_FLEXIOCLKSEL_SEL(0):
635             freq = CLK_FRO_DIV2_CLK;
636             break;
637 
638         case CLKCTL1_FLEXIOCLKSEL_SEL(1):
639             freq = CLOCK_GetAudioPllClkFreq();
640             break;
641 
642         case CLKCTL1_FLEXIOCLKSEL_SEL(2):
643             freq = CLOCK_GetMclkInClkFreq();
644             break;
645 
646         case CLKCTL1_FLEXIOCLKSEL_SEL(3):
647             freq = CLOCK_GetFRGClock(17);
648             break;
649 
650         default:
651             freq = 0U;
652             break;
653     }
654 
655     return freq / ((CLKCTL1->FLEXIOCLKDIV & CLKCTL1_FLEXIOCLKDIV_DIV_MASK) + 1U);
656 }
657 
658 /* Get CTIMER Clk */
659 /*! brief  Return Frequency of Ctimer Clock
660  *  param   id    : ctimer index to get frequency.
661  *  return Frequency of Ctimer Clock
662  */
CLOCK_GetCtimerClkFreq(uint32_t id)663 uint32_t CLOCK_GetCtimerClkFreq(uint32_t id)
664 {
665     uint32_t freq = 0U;
666 
667     switch ((CLKCTL1->CT32BITFCLKSEL[id]) & CLKCTL1_CT32BITFCLKSEL_SEL_MASK)
668     {
669         case CLKCTL1_CT32BITFCLKSEL_SEL(0):
670             freq = CLOCK_GetMainClkFreq();
671             break;
672 
673         case CLKCTL1_CT32BITFCLKSEL_SEL(1):
674             freq = CLK_FRO_CLK;
675             break;
676 
677         case CLKCTL1_CT32BITFCLKSEL_SEL(2):
678             freq = CLOCK_GetAudioPllClkFreq();
679             break;
680 
681         case CLKCTL1_CT32BITFCLKSEL_SEL(3):
682             freq = CLOCK_GetMclkInClkFreq();
683             break;
684 
685         case CLKCTL1_CT32BITFCLKSEL_SEL(4):
686             freq = CLOCK_GetWakeClk32KFreq();
687             break;
688 
689         default:
690             freq = 0U;
691             break;
692     }
693 
694     return freq;
695 }
696 
697 /*! @brief  Return Frequency of FLEXSPI Clock
698  *  @param  id : flexspi index to get frequency.
699  *  @return Frequency of Flexspi.
700  */
CLOCK_GetFlexspiClkFreq(uint32_t id)701 uint32_t CLOCK_GetFlexspiClkFreq(uint32_t id)
702 {
703     uint32_t freq = 0U;
704     uint32_t clkSel;
705     uint32_t clkDiv;
706 
707     assert(id <= 1U);
708 
709     if (id == 0U)
710     {
711         clkSel = CLKCTL0->FLEXSPI0FCLKSEL & CLKCTL0_FLEXSPI0FCLKSEL_SEL_MASK;
712         clkDiv = CLKCTL0->FLEXSPI0FCLKDIV & CLKCTL0_FLEXSPI0FCLKDIV_DIV_MASK;
713     }
714     else
715     {
716         clkSel = CLKCTL0->FLEXSPI1FCLKSEL & CLKCTL0_FLEXSPI1FCLKSEL_SEL_MASK;
717         clkDiv = CLKCTL0->FLEXSPI1FCLKDIV & CLKCTL0_FLEXSPI1FCLKDIV_DIV_MASK;
718     }
719 
720     switch (clkSel)
721     {
722         case CLKCTL0_FLEXSPI0FCLKSEL_SEL(0):
723             freq = CLOCK_GetMainClkFreq();
724             break;
725 
726         case CLKCTL0_FLEXSPI0FCLKSEL_SEL(1):
727             freq = CLOCK_GetMainPllClkFreq();
728             break;
729 
730         case CLKCTL0_FLEXSPI0FCLKSEL_SEL(2):
731             freq = CLOCK_GetAux0PllClkFreq();
732             break;
733 
734         case CLKCTL0_FLEXSPI0FCLKSEL_SEL(3):
735             freq = CLK_FRO_CLK;
736             break;
737 
738         case CLKCTL0_FLEXSPI0FCLKSEL_SEL(4):
739             freq = CLOCK_GetAux1PllClkFreq();
740             break;
741 
742         default:
743             freq = 0U;
744             break;
745     }
746 
747     return freq / (clkDiv + 1U);
748 }
749 
750 /* Get SCT Clk */
751 /*! brief  Return Frequency of sct
752  *  return Frequency of sct clk
753  */
CLOCK_GetSctClkFreq(void)754 uint32_t CLOCK_GetSctClkFreq(void)
755 {
756     uint32_t freq = 0U;
757 
758     switch ((CLKCTL0->SCTFCLKSEL) & CLKCTL0_SCTFCLKSEL_SEL_MASK)
759     {
760         case CLKCTL0_SCTFCLKSEL_SEL(0):
761             freq = CLOCK_GetMainClkFreq();
762             break;
763 
764         case CLKCTL0_SCTFCLKSEL_SEL(1):
765             freq = CLOCK_GetMainPllClkFreq();
766             break;
767 
768         case CLKCTL0_SCTFCLKSEL_SEL(2):
769             freq = CLOCK_GetAux0PllClkFreq();
770             break;
771 
772         case CLKCTL0_SCTFCLKSEL_SEL(3):
773             freq = CLK_FRO_CLK;
774             break;
775 
776         case CLKCTL0_SCTFCLKSEL_SEL(4):
777             freq = CLOCK_GetAux1PllClkFreq();
778             break;
779 
780         case CLKCTL0_SCTFCLKSEL_SEL(5):
781             freq = CLOCK_GetAudioPllClkFreq();
782             break;
783 
784         default:
785             freq = 0U;
786             break;
787     }
788 
789     return freq / ((CLKCTL0->SCTIN7CLKDIV & CLKCTL0_SCTIN7CLKDIV_DIV_MASK) + 1U);
790 }
791 
792 /*! brief  Return Frequency of mclk
793  *  return Frequency of mclk clk
794  */
CLOCK_GetMclkClkFreq(void)795 uint32_t CLOCK_GetMclkClkFreq(void)
796 {
797     uint32_t freq = 0U;
798 
799     if ((CLKCTL1->AUDIOMCLKSEL & CLKCTL1_AUDIOMCLKSEL_SEL_MASK) == CLKCTL1_AUDIOMCLKSEL_SEL(0))
800     {
801         freq = CLK_FRO_DIV8_CLK;
802     }
803     else if ((CLKCTL1->AUDIOMCLKSEL & CLKCTL1_AUDIOMCLKSEL_SEL_MASK) == CLKCTL1_AUDIOMCLKSEL_SEL(1))
804     {
805         freq = CLOCK_GetAudioPllClkFreq();
806     }
807     else
808     {
809         freq = 0U;
810     }
811 
812     return freq / ((CLKCTL1->AUDIOMCLKDIV & CLKCTL1_AUDIOMCLKDIV_DIV_MASK) + 1U);
813 }
814 
815 /*! @brief  Return Frequency of WDT clk
816  *  @param  id : WDT index to get frequency.
817  *  @return Frequency of WDT clk
818  */
CLOCK_GetWdtClkFreq(uint32_t id)819 uint32_t CLOCK_GetWdtClkFreq(uint32_t id)
820 {
821     uint32_t freq = 0U;
822 
823     assert(id <= 1U);
824 
825     if (id == 0U)
826     {
827         if ((CLKCTL0->WDT0FCLKSEL & CLKCTL0_WDT0FCLKSEL_SEL_MASK) == CLKCTL0_WDT0FCLKSEL_SEL(0))
828         {
829             freq = CLOCK_GetLpOscFreq();
830         }
831         else
832         {
833             freq = 0U;
834         }
835     }
836     else
837     {
838         if ((CLKCTL1->WDT1FCLKSEL & CLKCTL1_WDT1FCLKSEL_SEL_MASK) == CLKCTL1_WDT1FCLKSEL_SEL(0))
839         {
840             freq = CLOCK_GetLpOscFreq();
841         }
842         else
843         {
844             freq = 0U;
845         }
846     }
847 
848     return freq;
849 }
850 
851 /*! brief  Return Frequency of systick clk
852  *  return Frequency of systick clk
853  */
CLOCK_GetSystickClkFreq(void)854 uint32_t CLOCK_GetSystickClkFreq(void)
855 {
856     uint32_t freq = 0U;
857 
858     switch (CLKCTL0->SYSTICKFCLKSEL & CLKCTL0_SYSTICKFCLKSEL_SEL_MASK)
859     {
860         case CLKCTL0_SYSTICKFCLKSEL_SEL(0):
861             freq = CLOCK_GetMainClkFreq() / ((CLKCTL0->SYSTICKFCLKDIV & CLKCTL0_SYSTICKFCLKDIV_DIV_MASK) + 1U);
862             break;
863 
864         case CLKCTL0_SYSTICKFCLKSEL_SEL(1):
865             freq = CLOCK_GetLpOscFreq();
866             break;
867 
868         case CLKCTL0_SYSTICKFCLKSEL_SEL(2):
869             freq = CLOCK_GetOsc32KFreq();
870             break;
871 
872         default:
873             freq = 0U;
874             break;
875     }
876 
877     return freq;
878 }
879 
880 /*! brief  Return Frequency of SDIO clk
881  *  param id : SDIO index to get frequency.
882  *  return Frequency of SDIO clk
883  */
CLOCK_GetSdioClkFreq(uint32_t id)884 uint32_t CLOCK_GetSdioClkFreq(uint32_t id)
885 {
886     uint32_t freq = 0U;
887     volatile uint32_t *pClkSel;
888     volatile uint32_t *pClkDiv;
889 
890     assert(id <= 1U);
891 
892     if (id == 0U)
893     {
894         pClkSel = &CLKCTL0->SDIO0FCLKSEL;
895         pClkDiv = &CLKCTL0->SDIO0FCLKDIV;
896     }
897     else
898     {
899         pClkSel = &CLKCTL0->SDIO1FCLKSEL;
900         pClkDiv = &CLKCTL0->SDIO1FCLKDIV;
901     }
902 
903     switch ((*pClkSel) & CLKCTL0_SDIO0FCLKSEL_SEL_MASK)
904     {
905         case CLKCTL0_SDIO0FCLKSEL_SEL(0):
906             freq = CLOCK_GetMainClkFreq();
907             break;
908 
909         case CLKCTL0_SDIO0FCLKSEL_SEL(1):
910             freq = CLOCK_GetMainPllClkFreq();
911             break;
912 
913         case CLKCTL0_SDIO0FCLKSEL_SEL(2):
914             freq = CLOCK_GetAux0PllClkFreq();
915             break;
916 
917         case CLKCTL0_SDIO0FCLKSEL_SEL(3):
918             freq = CLK_FRO_DIV2_CLK;
919             break;
920 
921         case CLKCTL0_SDIO0FCLKSEL_SEL(4):
922             freq = CLOCK_GetAux1PllClkFreq();
923             break;
924 
925         default:
926             freq = 0U;
927             break;
928     }
929 
930     return freq / (((*pClkDiv) & CLKCTL0_SDIO0FCLKDIV_DIV_MASK) + 1U);
931 }
932 
933 /*! @brief  Return Frequency of I3C clk
934  *  @return Frequency of I3C clk
935  */
CLOCK_GetI3cClkFreq(void)936 uint32_t CLOCK_GetI3cClkFreq(void)
937 {
938     uint32_t freq = 0U;
939 
940     switch (CLKCTL1->I3C01FCLKSEL & CLKCTL1_I3C01FCLKSEL_SEL_MASK)
941     {
942         case CLKCTL1_I3C01FCLKSEL_SEL(0):
943             freq = CLOCK_GetMainClkFreq();
944             break;
945 
946         case CLKCTL1_I3C01FCLKSEL_SEL(1):
947             freq = CLK_FRO_DIV8_CLK;
948             break;
949 
950         default:
951             freq = 0U;
952             break;
953     }
954 
955     return freq / ((CLKCTL1->I3C01FCLKDIV & CLKCTL1_I3C01FCLKDIV_DIV_MASK) + 1U);
956 }
957 
958 /*! brief  Return Frequency of USB clk
959  *  return Frequency of USB clk
960  */
CLOCK_GetUsbClkFreq(void)961 uint32_t CLOCK_GetUsbClkFreq(void)
962 {
963     uint32_t freq = 0U;
964 
965     switch (CLKCTL0->USBHSFCLKSEL & CLKCTL0_USBHSFCLKSEL_SEL_MASK)
966     {
967         case CLKCTL0_USBHSFCLKSEL_SEL(0):
968             freq = CLOCK_GetXtalInClkFreq();
969             break;
970         case CLKCTL0_USBHSFCLKSEL_SEL(1):
971             freq = CLOCK_GetMainClkFreq();
972             break;
973         case CLKCTL0_USBHSFCLKSEL_SEL(3):
974             freq = CLOCK_GetAux0PllClkFreq();
975             break;
976         default:
977             freq = 0U;
978             break;
979     }
980 
981     return freq / ((CLKCTL0->USBHSFCLKDIV & CLKCTL0_USBHSFCLKDIV_DIV_MASK) + 1U);
982 }
983 
984 /*! brief  Return Frequency of DMIC clk
985  *  return Frequency of DMIC clk
986  */
CLOCK_GetDmicClkFreq(void)987 uint32_t CLOCK_GetDmicClkFreq(void)
988 {
989     uint32_t freq = 0U;
990 
991     switch ((CLKCTL1->DMIC0FCLKSEL) & CLKCTL1_DMIC0FCLKSEL_SEL_MASK)
992     {
993         case CLKCTL1_DMIC0FCLKSEL_SEL(0):
994             freq = CLK_FRO_DIV4_CLK;
995             break;
996 
997         case CLKCTL1_DMIC0FCLKSEL_SEL(1):
998             freq = CLOCK_GetAudioPllClkFreq();
999             break;
1000 
1001         case CLKCTL1_DMIC0FCLKSEL_SEL(2):
1002             freq = CLOCK_GetMclkInClkFreq();
1003             break;
1004 
1005         case CLKCTL1_DMIC0FCLKSEL_SEL(3):
1006             freq = CLOCK_GetLpOscFreq();
1007             break;
1008 
1009         case CLKCTL1_DMIC0FCLKSEL_SEL(4):
1010             freq = CLOCK_GetWakeClk32KFreq();
1011             break;
1012 
1013         default:
1014             freq = 0U;
1015             break;
1016     }
1017 
1018     return freq / ((CLKCTL1->DMIC0FCLKDIV & CLKCTL1_DMIC0FCLKDIV_DIV_MASK) + 1U);
1019 }
1020 
1021 /*! brief  Return Frequency of ACMP clk
1022  *  return Frequency of ACMP clk
1023  */
CLOCK_GetAcmpClkFreq(void)1024 uint32_t CLOCK_GetAcmpClkFreq(void)
1025 {
1026     uint32_t freq = 0U;
1027 
1028     switch ((CLKCTL1->ACMP0FCLKSEL) & CLKCTL1_ACMP0FCLKSEL_SEL_MASK)
1029     {
1030         case CLKCTL1_ACMP0FCLKSEL_SEL(0):
1031             freq = CLOCK_GetMainClkFreq();
1032             break;
1033 
1034         case CLKCTL1_ACMP0FCLKSEL_SEL(1):
1035             freq = CLK_FRO_DIV4_CLK;
1036             break;
1037 
1038         case CLKCTL1_ACMP0FCLKSEL_SEL(2):
1039             freq = CLOCK_GetAux0PllClkFreq();
1040             break;
1041 
1042         case CLKCTL1_ACMP0FCLKSEL_SEL(3):
1043             freq = CLOCK_GetAux1PllClkFreq();
1044             break;
1045 
1046         default:
1047             freq = 0U;
1048             break;
1049     }
1050 
1051     return freq / ((CLKCTL1->ACMP0FCLKDIV & CLKCTL1_ACMP0FCLKDIV_DIV_MASK) + 1U);
1052 }
1053 
1054 /*! @brief  Return Frequency of GPU functional Clock
1055  *  @return Frequency of GPU functional Clock
1056  */
CLOCK_GetGpuClkFreq(void)1057 uint32_t CLOCK_GetGpuClkFreq(void)
1058 {
1059     uint32_t freq = 0U;
1060 
1061     switch (CLKCTL0->GPUCLKSEL & CLKCTL0_GPUCLKSEL_SEL_MASK)
1062     {
1063         case CLKCTL0_GPUCLKSEL_SEL(0):
1064             freq = CLOCK_GetMainClkFreq();
1065             break;
1066 
1067         case CLKCTL0_GPUCLKSEL_SEL(1):
1068             freq = CLK_FRO_CLK;
1069             break;
1070 
1071         case CLKCTL0_GPUCLKSEL_SEL(2):
1072             freq = CLOCK_GetMainPllClkFreq();
1073             break;
1074 
1075         case CLKCTL0_GPUCLKSEL_SEL(3):
1076             freq = CLOCK_GetAux0PllClkFreq();
1077             break;
1078 
1079         case CLKCTL0_GPUCLKSEL_SEL(4):
1080             freq = CLOCK_GetAux1PllClkFreq();
1081             break;
1082 
1083         default:
1084             freq = 0U;
1085             break;
1086     }
1087 
1088     return freq / ((CLKCTL0->GPUCLKDIV & CLKCTL0_GPUCLKDIV_DIV_MASK) + 1U);
1089 }
1090 
1091 /*! @brief  Return Frequency of DCNano Pixel functional Clock
1092  *  @return Frequency of DCNano pixel functional Clock
1093  */
CLOCK_GetDcPixelClkFreq(void)1094 uint32_t CLOCK_GetDcPixelClkFreq(void)
1095 {
1096     uint32_t freq = 0U;
1097 
1098     switch (CLKCTL0->DCPIXELCLKSEL & CLKCTL0_DCPIXELCLKSEL_SEL_MASK)
1099     {
1100         case CLKCTL0_DCPIXELCLKSEL_SEL(0):
1101             freq = CLOCK_GetMipiDphyClkFreq();
1102             break;
1103         case CLKCTL0_DCPIXELCLKSEL_SEL(1):
1104             freq = CLOCK_GetMainClkFreq();
1105             break;
1106 
1107         case CLKCTL0_DCPIXELCLKSEL_SEL(2):
1108             freq = CLK_FRO_CLK;
1109             break;
1110 
1111         case CLKCTL0_DCPIXELCLKSEL_SEL(3):
1112             freq = CLOCK_GetMainPllClkFreq();
1113             break;
1114 
1115         case CLKCTL0_DCPIXELCLKSEL_SEL(4):
1116             freq = CLOCK_GetAux0PllClkFreq();
1117             break;
1118 
1119         case CLKCTL0_DCPIXELCLKSEL_SEL(5):
1120             freq = CLOCK_GetAux1PllClkFreq();
1121             break;
1122 
1123         default:
1124             freq = 0U;
1125             break;
1126     }
1127 
1128     return freq / ((CLKCTL0->DCPIXELCLKDIV & CLKCTL0_DCPIXELCLKDIV_DIV_MASK) + 1U);
1129 }
1130 
1131 /*! @brief  Return Frequency of MIPI DPHY functional Clock
1132  *  @return Frequency of MIPI DPHY functional Clock
1133  */
CLOCK_GetMipiDphyClkFreq(void)1134 uint32_t CLOCK_GetMipiDphyClkFreq(void)
1135 {
1136     uint32_t freq = 0U;
1137 
1138     switch (CLKCTL0->DPHYCLKSEL & CLKCTL0_DPHYCLKSEL_SEL_MASK)
1139     {
1140         case CLKCTL0_DPHYCLKSEL_SEL(0):
1141             freq = CLK_FRO_CLK;
1142             break;
1143         case CLKCTL0_DPHYCLKSEL_SEL(1):
1144             freq = CLOCK_GetMainPllClkFreq();
1145             break;
1146 
1147         case CLKCTL0_DPHYCLKSEL_SEL(2):
1148             freq = CLOCK_GetAux0PllClkFreq();
1149             break;
1150 
1151         case CLKCTL0_DPHYCLKSEL_SEL(3):
1152             freq = CLOCK_GetAux1PllClkFreq();
1153             break;
1154 
1155         default:
1156             freq = 0U;
1157             break;
1158     }
1159 
1160     return freq / ((CLKCTL0->DPHYCLKDIV & CLKCTL0_DPHYCLKDIV_DIV_MASK) + 1U);
1161 }
1162 
1163 /*! @brief  Return Frequency of MIPI DPHY Esc RX functional Clock
1164  *  @return Frequency of MIPI DPHY Esc RX functional Clock
1165  */
CLOCK_GetMipiDphyEscRxClkFreq(void)1166 uint32_t CLOCK_GetMipiDphyEscRxClkFreq(void)
1167 {
1168     uint32_t freq = 0U;
1169 
1170     switch (CLKCTL0->DPHYESCCLKSEL & CLKCTL0_DPHYESCCLKSEL_SEL_MASK)
1171     {
1172         case CLKCTL0_DPHYESCCLKSEL_SEL(0):
1173             freq = CLK_FRO_CLK;
1174             break;
1175         case CLKCTL0_DPHYESCCLKSEL_SEL(1):
1176             freq = CLK_FRO_DIV16_CLK;
1177             break;
1178         case CLKCTL0_DPHYESCCLKSEL_SEL(2):
1179             freq = CLOCK_GetAux0PllClkFreq();
1180             break;
1181         case CLKCTL0_DPHYESCCLKSEL_SEL(3):
1182             freq = CLOCK_GetAux1PllClkFreq();
1183             break;
1184 
1185         default:
1186             freq = 0U;
1187             break;
1188     }
1189 
1190     return freq / ((CLKCTL0->DPHYESCRXCLKDIV & CLKCTL0_DPHYESCRXCLKDIV_DIV_MASK) + 1U);
1191 }
1192 
1193 /*! @brief  Return Frequency of MIPI DPHY Esc Tx functional Clock
1194  *  @return Frequency of MIPI DPHY Esc Tx functional Clock
1195  */
CLOCK_GetMipiDphyEscTxClkFreq(void)1196 uint32_t CLOCK_GetMipiDphyEscTxClkFreq(void)
1197 {
1198     return CLOCK_GetMipiDphyEscRxClkFreq() / ((CLKCTL0->DPHYESCTXCLKDIV & CLKCTL0_DPHYESCTXCLKDIV_DIV_MASK) + 1U);
1199 }
1200 
1201 /* Get IP Clk */
1202 /*! brief  Return Frequency of selected clock
1203  *  return Frequency of selected clock
1204  */
CLOCK_GetFreq(clock_name_t clockName)1205 uint32_t CLOCK_GetFreq(clock_name_t clockName)
1206 {
1207     uint32_t freq = 0U;
1208 
1209     switch (clockName)
1210     {
1211         case kCLOCK_CoreSysClk:
1212         case kCLOCK_BusClk:
1213             freq = CLOCK_GetMainClkFreq() / ((CLKCTL0->SYSCPUAHBCLKDIV & CLKCTL0_SYSCPUAHBCLKDIV_DIV_MASK) + 1U);
1214             break;
1215         case kCLOCK_MclkClk:
1216             freq = CLOCK_GetMclkClkFreq();
1217             break;
1218         case kCLOCK_ClockOutClk:
1219             freq = CLOCK_GetClockOutClkFreq();
1220             break;
1221         case kCLOCK_AdcClk:
1222             freq = CLOCK_GetAdcClkFreq();
1223             break;
1224         case kCLOCK_Flexspi0Clk:
1225             freq = CLOCK_GetFlexspiClkFreq(0U);
1226             break;
1227         case kCLOCK_Flexspi1Clk:
1228             freq = CLOCK_GetFlexspiClkFreq(1U);
1229             break;
1230         case kCLOCK_SctClk:
1231             freq = CLOCK_GetSctClkFreq();
1232             break;
1233         case kCLOCK_Wdt0Clk:
1234             freq = CLOCK_GetWdtClkFreq(0U);
1235             break;
1236         case kCLOCK_Wdt1Clk:
1237             freq = CLOCK_GetWdtClkFreq(1U);
1238             break;
1239         case kCLOCK_SystickClk:
1240             freq = CLOCK_GetSystickClkFreq();
1241             break;
1242         case kCLOCK_Sdio0Clk:
1243             freq = CLOCK_GetSdioClkFreq(0U);
1244             break;
1245         case kCLOCK_Sdio1Clk:
1246             freq = CLOCK_GetSdioClkFreq(1U);
1247             break;
1248         case kCLOCK_I3cClk:
1249             freq = CLOCK_GetI3cClkFreq();
1250             break;
1251         case kCLOCK_UsbClk:
1252             freq = CLOCK_GetUsbClkFreq();
1253             break;
1254         case kCLOCK_DmicClk:
1255             freq = CLOCK_GetDmicClkFreq();
1256             break;
1257         case kCLOCK_DspCpuClk:
1258             freq = CLOCK_GetDspMainClkFreq() / ((CLKCTL1->DSPCPUCLKDIV & CLKCTL1_DSPCPUCLKDIV_DIV_MASK) + 1U);
1259             break;
1260         case kCLOCK_AcmpClk:
1261             freq = CLOCK_GetAcmpClkFreq();
1262             break;
1263         case kCLOCK_Flexcomm0Clk:
1264             freq = CLOCK_GetFlexcommClkFreq(0U);
1265             break;
1266         case kCLOCK_Flexcomm1Clk:
1267             freq = CLOCK_GetFlexcommClkFreq(1U);
1268             break;
1269         case kCLOCK_Flexcomm2Clk:
1270             freq = CLOCK_GetFlexcommClkFreq(2U);
1271             break;
1272         case kCLOCK_Flexcomm3Clk:
1273             freq = CLOCK_GetFlexcommClkFreq(3U);
1274             break;
1275         case kCLOCK_Flexcomm4Clk:
1276             freq = CLOCK_GetFlexcommClkFreq(4U);
1277             break;
1278         case kCLOCK_Flexcomm5Clk:
1279             freq = CLOCK_GetFlexcommClkFreq(5U);
1280             break;
1281         case kCLOCK_Flexcomm6Clk:
1282             freq = CLOCK_GetFlexcommClkFreq(6U);
1283             break;
1284         case kCLOCK_Flexcomm7Clk:
1285             freq = CLOCK_GetFlexcommClkFreq(7U);
1286             break;
1287         case kCLOCK_Flexcomm8Clk:
1288             freq = CLOCK_GetFlexcommClkFreq(8U);
1289             break;
1290         case kCLOCK_Flexcomm9Clk:
1291             freq = CLOCK_GetFlexcommClkFreq(9U);
1292             break;
1293         case kCLOCK_Flexcomm10Clk:
1294             freq = CLOCK_GetFlexcommClkFreq(10U);
1295             break;
1296         case kCLOCK_Flexcomm11Clk:
1297             freq = CLOCK_GetFlexcommClkFreq(11U);
1298             break;
1299         case kCLOCK_Flexcomm12Clk:
1300             freq = CLOCK_GetFlexcommClkFreq(12U);
1301             break;
1302         case kCLOCK_Flexcomm13Clk:
1303             freq = CLOCK_GetFlexcommClkFreq(13U);
1304             break;
1305         case kCLOCK_Flexcomm14Clk:
1306             freq = CLOCK_GetFlexcommClkFreq(14U);
1307             break;
1308         case kCLOCK_Flexcomm15Clk:
1309             freq = CLOCK_GetFlexcommClkFreq(15U);
1310             break;
1311         case kCLOCK_Flexcomm16Clk:
1312             freq = CLOCK_GetFlexcommClkFreq(16U);
1313             break;
1314         case kCLOCK_FlexioClk:
1315             freq = CLOCK_GetFlexioClkFreq();
1316             break;
1317         case kCLOCK_GpuClk:
1318             freq = CLOCK_GetGpuClkFreq();
1319             break;
1320         case kCLOCK_DcPixelClk:
1321             freq = CLOCK_GetDcPixelClkFreq();
1322             break;
1323         case kCLOCK_MipiDphyClk:
1324             freq = CLOCK_GetMipiDphyClkFreq();
1325             break;
1326         case kCLOCK_MipiDphyEscRxClk:
1327             freq = CLOCK_GetMipiDphyEscRxClkFreq();
1328             break;
1329         case kCLOCK_MipiDphyEscTxClk:
1330             freq = CLOCK_GetMipiDphyEscTxClkFreq();
1331             break;
1332         default:
1333             freq = 0U;
1334             break;
1335     }
1336 
1337     return freq;
1338 }
1339 
1340 /* Set FRG Clk */
1341 /*! brief  Set output of the Fractional baud rate generator
1342  * param   config    : Configuration to set to FRGn clock.
1343  */
CLOCK_SetFRGClock(const clock_frg_clk_config_t * config)1344 void CLOCK_SetFRGClock(const clock_frg_clk_config_t *config)
1345 {
1346     uint32_t i = config->num;
1347 
1348     assert(i <= 17U);
1349     assert(config->divider == 255U); /* Always set to 0xFF to use with the fractional baudrate generator.*/
1350 
1351     if (i == 17U)
1352     {
1353         CLKCTL1->FRG17CLKSEL = (uint32_t)config->sfg_clock_src;
1354         CLKCTL1->FRG17CTL    = (CLKCTL1_FRG17CTL_MULT(config->mult) | CLKCTL1_FRG17CTL_DIV(config->divider));
1355     }
1356     else
1357     {
1358         CLKCTL1->FLEXCOMM[i].FRGCLKSEL = (uint32_t)config->sfg_clock_src;
1359         CLKCTL1->FLEXCOMM[i].FRGCTL    = (CLKCTL1_FRGCTL_MULT(config->mult) | CLKCTL1_FRGCTL_DIV(config->divider));
1360     }
1361 }
1362 
1363 /* Initialize the SYSTEM PLL Clk */
1364 /*! brief  Initialize the System PLL.
1365  *  param  config    : Configuration to set to PLL.
1366  */
CLOCK_InitSysPll(const clock_sys_pll_config_t * config)1367 void CLOCK_InitSysPll(const clock_sys_pll_config_t *config)
1368 {
1369     /* Power down SYSPLL before change fractional settings */
1370     SYSCTL0->PDRUNCFG0_SET = SYSCTL0_PDRUNCFG0_SYSPLLLDO_PD_MASK | SYSCTL0_PDRUNCFG0_SYSPLLANA_PD_MASK;
1371 
1372     CLKCTL0->SYSPLL0CLKSEL = (uint32_t)config->sys_pll_src;
1373     CLKCTL0->SYSPLL0NUM    = config->numerator;
1374     CLKCTL0->SYSPLL0DENOM  = config->denominator;
1375     switch (config->sys_pll_mult)
1376     {
1377         case kCLOCK_SysPllMult16:
1378             CLKCTL0->SYSPLL0CTL0 =
1379                 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(16);
1380             break;
1381         case kCLOCK_SysPllMult17:
1382             CLKCTL0->SYSPLL0CTL0 =
1383                 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(17);
1384             break;
1385         case kCLOCK_SysPllMult18:
1386             CLKCTL0->SYSPLL0CTL0 =
1387                 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(18);
1388             break;
1389         case kCLOCK_SysPllMult19:
1390             CLKCTL0->SYSPLL0CTL0 =
1391                 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(19);
1392             break;
1393         case kCLOCK_SysPllMult20:
1394             CLKCTL0->SYSPLL0CTL0 =
1395                 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(20);
1396             break;
1397         case kCLOCK_SysPllMult21:
1398             CLKCTL0->SYSPLL0CTL0 =
1399                 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(21);
1400             break;
1401         case kCLOCK_SysPllMult22:
1402             CLKCTL0->SYSPLL0CTL0 =
1403                 (CLKCTL0->SYSPLL0CTL0 & ~CLKCTL0_SYSPLL0CTL0_MULT_MASK) | CLKCTL0_SYSPLL0CTL0_MULT(22);
1404             break;
1405         default:
1406             assert(false);
1407             break;
1408     }
1409     /* Clear System PLL reset*/
1410     CLKCTL0->SYSPLL0CTL0 &= ~CLKCTL0_SYSPLL0CTL0_RESET_MASK;
1411     /* Power up SYSPLL*/
1412     SYSCTL0->PDRUNCFG0_CLR = SYSCTL0_PDRUNCFG0_SYSPLLLDO_PD_MASK | SYSCTL0_PDRUNCFG0_SYSPLLANA_PD_MASK;
1413     SDK_DelayAtLeastUs((CLKCTL0->SYSPLL0LOCKTIMEDIV2 & CLKCTL0_SYSPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 2U,
1414                        SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1415     /* Set System PLL HOLDRINGOFF_ENA */
1416     CLKCTL0->SYSPLL0CTL0 |= CLKCTL0_SYSPLL0CTL0_HOLDRINGOFF_ENA_MASK;
1417     SDK_DelayAtLeastUs((CLKCTL0->SYSPLL0LOCKTIMEDIV2 & CLKCTL0_SYSPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 6U,
1418                        SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1419     /* Clear System PLL HOLDRINGOFF_ENA*/
1420     CLKCTL0->SYSPLL0CTL0 &= ~CLKCTL0_SYSPLL0CTL0_HOLDRINGOFF_ENA_MASK;
1421     SDK_DelayAtLeastUs((CLKCTL0->SYSPLL0LOCKTIMEDIV2 & CLKCTL0_SYSPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 3U,
1422                        SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1423 }
1424 
1425 /* Initialize the System PLL PFD */
1426 /*! brief Initialize the System PLL PFD.
1427  *  param pfd    : Which PFD clock to enable.
1428  *  param divider    : The PFD divider value.
1429  *  note It is recommended that PFD settings are kept between 12-35.
1430  */
CLOCK_InitSysPfd(clock_pfd_t pfd,uint8_t divider)1431 void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t divider)
1432 {
1433     uint32_t pfdIndex = (uint32_t)pfd;
1434     uint32_t syspfd;
1435 
1436     syspfd = CLKCTL0->SYSPLL0PFD &
1437              ~(((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_CLKGATE_MASK | (uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_MASK)
1438                << (8UL * pfdIndex));
1439 
1440     /* Disable the clock output first. */
1441     CLKCTL0->SYSPLL0PFD = syspfd | ((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
1442 
1443     /* Set the new value and enable output. */
1444     CLKCTL0->SYSPLL0PFD = syspfd | ((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0(divider) << (8UL * pfdIndex));
1445     /* Wait for output becomes stable. */
1446     while ((CLKCTL0->SYSPLL0PFD & ((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_CLKRDY_MASK << (8UL * pfdIndex))) == 0UL)
1447     {
1448     }
1449     /* Clear ready status flag. */
1450     CLKCTL0->SYSPLL0PFD |= ((uint32_t)CLKCTL0_SYSPLL0PFD_PFD0_CLKRDY_MASK << (8UL * pfdIndex));
1451 }
1452 
1453 /* Initialize the Audio PLL Clk */
1454 /*! brief  Initialize the audio PLL.
1455  *  param  config    : Configuration to set to PLL.
1456  */
CLOCK_InitAudioPll(const clock_audio_pll_config_t * config)1457 void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
1458 {
1459     /* Power down Audio PLL before change fractional settings */
1460     SYSCTL0->PDRUNCFG0_SET = SYSCTL0_PDRUNCFG0_AUDPLLLDO_PD_MASK | SYSCTL0_PDRUNCFG0_AUDPLLANA_PD_MASK;
1461 
1462     CLKCTL1->AUDIOPLL0CLKSEL = (uint32_t)config->audio_pll_src;
1463     CLKCTL1->AUDIOPLL0NUM    = config->numerator;
1464     CLKCTL1->AUDIOPLL0DENOM  = config->denominator;
1465 
1466     switch (config->audio_pll_mult)
1467     {
1468         case kCLOCK_AudioPllMult16:
1469             CLKCTL1->AUDIOPLL0CTL0 =
1470                 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(16);
1471             break;
1472         case kCLOCK_AudioPllMult17:
1473             CLKCTL1->AUDIOPLL0CTL0 =
1474                 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(17);
1475             break;
1476         case kCLOCK_AudioPllMult18:
1477             CLKCTL1->AUDIOPLL0CTL0 =
1478                 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(18);
1479             break;
1480         case kCLOCK_AudioPllMult19:
1481             CLKCTL1->AUDIOPLL0CTL0 =
1482                 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(19);
1483             break;
1484         case kCLOCK_AudioPllMult20:
1485             CLKCTL1->AUDIOPLL0CTL0 =
1486                 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(20);
1487             break;
1488         case kCLOCK_AudioPllMult21:
1489             CLKCTL1->AUDIOPLL0CTL0 =
1490                 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(21);
1491             break;
1492         case kCLOCK_AudioPllMult22:
1493             CLKCTL1->AUDIOPLL0CTL0 =
1494                 (CLKCTL1->AUDIOPLL0CTL0 & ~CLKCTL1_AUDIOPLL0CTL0_MULT_MASK) | CLKCTL1_AUDIOPLL0CTL0_MULT(22);
1495             break;
1496         default:
1497             assert(false);
1498             break;
1499     }
1500     /* Clear Audio PLL reset*/
1501     CLKCTL1->AUDIOPLL0CTL0 &= ~CLKCTL1_AUDIOPLL0CTL0_RESET_MASK;
1502     /* Power up Audio PLL*/
1503     SYSCTL0->PDRUNCFG0_CLR = SYSCTL0_PDRUNCFG0_AUDPLLLDO_PD_MASK | SYSCTL0_PDRUNCFG0_AUDPLLANA_PD_MASK;
1504     SDK_DelayAtLeastUs((CLKCTL1->AUDIOPLL0LOCKTIMEDIV2 & CLKCTL1_AUDIOPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 2U,
1505                        SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1506     /* Set Audio PLL HOLDRINGOFF_ENA */
1507     CLKCTL1->AUDIOPLL0CTL0 |= CLKCTL1_AUDIOPLL0CTL0_HOLDRINGOFF_ENA_MASK;
1508     SDK_DelayAtLeastUs((CLKCTL1->AUDIOPLL0LOCKTIMEDIV2 & CLKCTL1_AUDIOPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 6U,
1509                        SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1510     /* Clear Audio PLL HOLDRINGOFF_ENA*/
1511     CLKCTL1->AUDIOPLL0CTL0 &= ~CLKCTL1_AUDIOPLL0CTL0_HOLDRINGOFF_ENA_MASK;
1512     SDK_DelayAtLeastUs((CLKCTL1->AUDIOPLL0LOCKTIMEDIV2 & CLKCTL1_AUDIOPLL0LOCKTIMEDIV2_LOCKTIMEDIV2_MASK) / 3U,
1513                        SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1514 }
1515 
1516 /* Initialize the Audio PLL PFD */
1517 /*! brief Initialize the audio PLL PFD.
1518  *  param pfd    : Which PFD clock to enable.
1519  *  param divider    : The PFD divider value.
1520  *  note It is recommended that PFD settings are kept between 12-35.
1521  */
CLOCK_InitAudioPfd(clock_pfd_t pfd,uint8_t divider)1522 void CLOCK_InitAudioPfd(clock_pfd_t pfd, uint8_t divider)
1523 {
1524     uint32_t pfdIndex = (uint32_t)pfd;
1525     uint32_t syspfd;
1526 
1527     syspfd = CLKCTL1->AUDIOPLL0PFD &
1528              ~(((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_CLKGATE_MASK | (uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_MASK)
1529                << (8UL * pfdIndex));
1530 
1531     /* Disable the clock output first. */
1532     CLKCTL1->AUDIOPLL0PFD = syspfd | ((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
1533 
1534     /* Set the new value and enable output. */
1535     CLKCTL1->AUDIOPLL0PFD = syspfd | ((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0(divider) << (8UL * pfdIndex));
1536     /* Wait for output becomes stable. */
1537     while ((CLKCTL1->AUDIOPLL0PFD & ((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_CLKRDY_MASK << (8UL * pfdIndex))) == 0UL)
1538     {
1539     }
1540     /* Clear ready status flag. */
1541     CLKCTL1->AUDIOPLL0PFD |= ((uint32_t)CLKCTL1_AUDIOPLL0PFD_PFD0_CLKRDY_MASK << (8UL * pfdIndex));
1542 }
1543 
1544 /*! @brief  Enable/Disable sys osc clock from external crystal clock.
1545  *  @param  enable : true to enable system osc clock, false to bypass system osc.
1546  *  @param  enableLowPower : true to enable low power mode, false to enable high gain mode.
1547  *  @param  delay_us : Delay time after OSC power up.
1548  */
CLOCK_EnableSysOscClk(bool enable,bool enableLowPower,uint32_t delay_us)1549 void CLOCK_EnableSysOscClk(bool enable, bool enableLowPower, uint32_t delay_us)
1550 {
1551     uint32_t ctrl = enableLowPower ? CLKCTL0_SYSOSCCTL0_LP_ENABLE_MASK : 0U;
1552 
1553     if (enable)
1554     {
1555         CLKCTL0->SYSOSCCTL0   = ctrl;
1556         CLKCTL0->SYSOSCBYPASS = 0U;
1557         SDK_DelayAtLeastUs(delay_us, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1558     }
1559     else
1560     {
1561         CLKCTL0->SYSOSCCTL0 = ctrl | CLKCTL0_SYSOSCCTL0_BYPASS_ENABLE_MASK;
1562     }
1563 }
1564 
1565 /*! @brief  Enable/Disable FRO clock output.
1566  *  @param  divOutEnable : Or'ed value of clock_fro_output_en_t to enable certain clock freq output.
1567  */
CLOCK_EnableFroClk(uint32_t divOutEnable)1568 void CLOCK_EnableFroClk(uint32_t divOutEnable)
1569 {
1570     if (divOutEnable != 0U)
1571     {
1572         /* Some FRO frequency need to be outputed. Wait FRO stable first in case FRO just get powered on. */
1573         while ((CLKCTL0->FROCLKSTATUS & CLKCTL0_FROCLKSTATUS_CLK_OK_MASK) == 0U)
1574         {
1575         }
1576     }
1577     else
1578     {
1579         /* Do nothing */
1580     }
1581     CLKCTL0->FRODIVOEN = divOutEnable & (uint32_t)kCLOCK_FroAllOutEn;
1582 }
1583 
CLOCK_EnableFroClkFreq(uint32_t targetFreq,uint32_t divOutEnable)1584 void CLOCK_EnableFroClkFreq(uint32_t targetFreq, uint32_t divOutEnable)
1585 {
1586     (void)CLOCK_FroTuneToFreq(targetFreq);
1587     CLOCK_EnableFroClk(divOutEnable);
1588 }
1589 
1590 #ifndef __XTENSA__
1591 /*! @brief  Enable/Disable FRO192M or FRO96M clock output.
1592  *  @param  froFreq : target fro frequency.
1593  *  @param  divOutEnable : Or'ed value of clock_fro_output_en_t to enable certain clock freq output.
1594  */
CLOCK_EnableFroClkRange(clock_fro_freq_t froFreq,uint32_t divOutEnable)1595 void CLOCK_EnableFroClkRange(clock_fro_freq_t froFreq, uint32_t divOutEnable)
1596 {
1597     uint32_t scTrim, rdTrim;
1598 
1599     OTP_INIT_API(CLOCK_GetFreq(kCLOCK_BusClk));
1600     if (froFreq == kCLOCK_Fro192M)
1601     {
1602         /* Read 192M FRO clock Trim settings from fuse. */
1603         OTP_FUSE_READ_API(FRO_192MHZ_SC_TRIM, &scTrim);
1604         OTP_FUSE_READ_API(FRO_192MHZ_RD_TRIM, &rdTrim);
1605     }
1606     else
1607     {
1608         /* Read 96M FRO clock Trim settings from fuse. */
1609         OTP_FUSE_READ_API(FRO_96MHZ_SC_TRIM, &scTrim);
1610         OTP_FUSE_READ_API(FRO_96MHZ_RD_TRIM, &rdTrim);
1611     }
1612     OTP_DEINIT_API();
1613 
1614     CLKCTL0->FRO_SCTRIM = CLKCTL0_FRO_SCTRIM_TRIM(scTrim);
1615     CLKCTL0->FRO_RDTRIM = CLKCTL0_FRO_RDTRIM_TRIM(rdTrim);
1616     CLKCTL0->FRO_CONTROL &= ~CLKCTL0_FRO_CONTROL_EXP_COUNT_MASK; /* Reset the EXP_COUNT. */
1617     CLOCK_EnableFroClk(divOutEnable);
1618 }
1619 #endif /* __XTENSA__ */
1620 
1621 /*! @brief  Enable LPOSC 1MHz clock.
1622  */
CLOCK_EnableLpOscClk(void)1623 void CLOCK_EnableLpOscClk(void)
1624 {
1625     /* No LPOSC enable/disable control in CLKCTL. Just wait LPOSC stable in case LPOSC just get powered on. */
1626     while ((CLKCTL0->LPOSCCTL0 & CLKCTL0_LPOSCCTL0_CLKRDY_MASK) == 0U)
1627     {
1628     }
1629 }
1630 
CLOCK_FroTuneToFreq(uint32_t targetFreq)1631 status_t CLOCK_FroTuneToFreq(uint32_t targetFreq)
1632 {
1633     uint32_t xtalFreq = CLOCK_GetXtalInClkFreq();
1634     uint32_t expected, up, low;
1635     uint32_t captured, trim;
1636 
1637     assert(xtalFreq);
1638     assert(targetFreq >= CLK_FRO_LOW_FREQ);
1639     assert(targetFreq <= CLK_FRO_HIGH_FREQ);
1640 
1641     if (xtalFreq == 0U)
1642     {
1643         /* The reference clock for the tuner is unavailable. */
1644         return kStatus_Fail;
1645     }
1646 
1647     targetFreq = (targetFreq / 4U);
1648 
1649     /* Avoid the need for 64-bit calculation. */
1650     targetFreq = targetFreq / 100U;
1651     xtalFreq   = xtalFreq / 100U;
1652 
1653     expected = ((targetFreq * 4095U) / xtalFreq + 6U) / 2U;
1654     up       = ((((targetFreq * 2047U) / xtalFreq) * 100085U) / 100000U) + 2U;
1655     low      = ((((targetFreq * 2048U) / xtalFreq) * 99915U + 100000U) / 100000U) + 3U;
1656 
1657     /* Start tuning */
1658     CLKCTL0->FRO_CONTROL = CLKCTL0_FRO_CONTROL_EXP_COUNT(expected) |
1659                            CLKCTL0_FRO_CONTROL_THRESH_RANGE_UP(up - expected) |
1660                            CLKCTL0_FRO_CONTROL_THRESH_RANGE_LOW(expected - low) | CLKCTL0_FRO_CONTROL_ENA_TUNE_MASK;
1661 
1662     while (true)
1663     {
1664         while ((CLKCTL0->FRO_CAPVAL & CLKCTL0_FRO_CAPVAL_DATA_VALID_MASK) == 0U)
1665         {
1666         }
1667 
1668         captured = CLKCTL0->FRO_CAPVAL & CLKCTL0_FRO_CAPVAL_CAPVAL_MASK;
1669         trim     = CLKCTL0->FRO_RDTRIM;
1670         /* Clear FRO_CAPVAL VALID flag */
1671         CLKCTL0->FRO_RDTRIM = trim;
1672         /* Reach the frequency range, then return. */
1673         if ((captured <= up) && (captured >= low))
1674         {
1675             break;
1676         }
1677     }
1678 
1679     CLKCTL0->FRO_CONTROL &= ~CLKCTL0_FRO_CONTROL_ENA_TUNE_MASK;
1680 
1681     return kStatus_Success;
1682 }
1683 
CLOCK_EnableFroTuning(bool enable)1684 void CLOCK_EnableFroTuning(bool enable)
1685 {
1686     uint32_t xtalFreq   = CLOCK_GetXtalInClkFreq();
1687     uint32_t targetFreq = CLK_FRO_DIV4_CLK;
1688     uint32_t expected, up, low;
1689     uint32_t captured, trim;
1690 
1691     assert(xtalFreq);
1692     assert(targetFreq > xtalFreq);
1693 
1694     if (enable)
1695     {
1696         /* Avoid the need for 64-bit calculation. */
1697         xtalFreq   = xtalFreq / 100U;
1698         targetFreq = targetFreq / 100U;
1699 
1700         expected = ((targetFreq * 4095U) / xtalFreq + 6U) / 2U;
1701         up       = (((targetFreq * 2047U) / xtalFreq) * 100085U) / 100000U + 2U;
1702         low      = (((targetFreq * 2048U) / xtalFreq) * 99915U + 100000U) / 100000U + 3U;
1703 
1704         /* Start tuning */
1705         CLKCTL0->FRO_CONTROL = CLKCTL0_FRO_CONTROL_EXP_COUNT(expected) |
1706                                CLKCTL0_FRO_CONTROL_THRESH_RANGE_UP(up - expected) |
1707                                CLKCTL0_FRO_CONTROL_THRESH_RANGE_LOW(expected - low) | CLKCTL0_FRO_CONTROL_ENA_TUNE_MASK;
1708 
1709         while (true)
1710         {
1711             while ((CLKCTL0->FRO_CAPVAL & CLKCTL0_FRO_CAPVAL_DATA_VALID_MASK) == 0U)
1712             {
1713             }
1714 
1715             captured = CLKCTL0->FRO_CAPVAL & CLKCTL0_FRO_CAPVAL_CAPVAL_MASK;
1716             trim     = CLKCTL0->FRO_RDTRIM;
1717             /* Clear FRO_CAPVAL VALID flag */
1718             CLKCTL0->FRO_RDTRIM = trim;
1719             /* Reach the frequency range, then return. */
1720             if ((captured <= up) && (captured >= low))
1721             {
1722                 break;
1723             }
1724         }
1725     }
1726     else
1727     {
1728         CLKCTL0->FRO_CONTROL &= ~CLKCTL0_FRO_CONTROL_ENA_TUNE_MASK;
1729     }
1730 }
1731 
1732 /*! @brief Enable USB HS device clock.
1733  *
1734  * This function enables USB HS device clock.
1735  */
CLOCK_EnableUsbHs0DeviceClock(clock_attach_id_t src,uint8_t divider)1736 void CLOCK_EnableUsbHs0DeviceClock(clock_attach_id_t src, uint8_t divider)
1737 {
1738     CLOCK_AttachClk(src);
1739     /* frequency division for usb ip clock */
1740     CLOCK_SetClkDiv(kCLOCK_DivUsbHsFclk, divider);
1741     /* Enable usbhs device clock */
1742     CLOCK_EnableClock(kCLOCK_UsbhsDevice);
1743 }
1744 
1745 /*! @brief Disable USB HS device clock.
1746  *
1747  * This function disables USB HS device clock.
1748  */
CLOCK_DisableUsbHs0DeviceClock(void)1749 void CLOCK_DisableUsbHs0DeviceClock(void)
1750 {
1751     /* Disable usbhs device clock */
1752     CLOCK_DisableClock(kCLOCK_UsbhsDevice);
1753 }
1754 
1755 /*! @brief Enable USB HS host clock.
1756  *
1757  * This function enables USB HS host clock.
1758  */
CLOCK_EnableUsbHs0HostClock(clock_attach_id_t src,uint8_t divider)1759 void CLOCK_EnableUsbHs0HostClock(clock_attach_id_t src, uint8_t divider)
1760 {
1761     CLOCK_AttachClk(src);
1762     /* frequency division for usb ip clock */
1763     CLOCK_SetClkDiv(kCLOCK_DivUsbHsFclk, divider);
1764     /* Enable usbhs host clock */
1765     CLOCK_EnableClock(kCLOCK_UsbhsHost);
1766 }
1767 
1768 /*! @brief Disable USB HS host clock.
1769  *
1770  * This function disables USB HS host clock.
1771  */
CLOCK_DisableUsbHs0HostClock(void)1772 void CLOCK_DisableUsbHs0HostClock(void)
1773 {
1774     /* Disable usbhs host clock */
1775     CLOCK_DisableClock(kCLOCK_UsbhsHost);
1776 }
1777 
1778 /*! brief Enable USB hs0PhyPll clock.
1779  *
1780  * param src  USB HS clock source.
1781  * param freq The frequency specified by src.
1782  * retval true The clock is set successfully.
1783  * retval false The clock source is invalid to get proper USB HS clock.
1784  */
CLOCK_EnableUsbHs0PhyPllClock(clock_attach_id_t src,uint32_t freq)1785 bool CLOCK_EnableUsbHs0PhyPllClock(clock_attach_id_t src, uint32_t freq)
1786 {
1787     uint32_t phyPllDiv  = 0U;
1788     uint16_t multiplier = 0U;
1789     bool retVal         = true;
1790 
1791     if (((uint32_t)(CLKCTL0->USBHSFCLKSEL & CLKCTL0_USBHSFCLKSEL_SEL_MASK)) != CLKCTL0_USBHSFCLKSEL_SEL(src))
1792     {
1793         retVal = false;
1794     }
1795 
1796     if ((480000000U % freq) != 0U)
1797     {
1798         retVal = false;
1799     }
1800 
1801     multiplier = (uint16_t)(480000000U / freq);
1802 
1803     switch (multiplier)
1804     {
1805         case 13U:
1806         {
1807             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(0U);
1808             break;
1809         }
1810         case 15U:
1811         {
1812             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(1U);
1813             break;
1814         }
1815         case 16U:
1816         {
1817             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(2U);
1818             break;
1819         }
1820         case 20U:
1821         {
1822             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(3U);
1823             break;
1824         }
1825         case 22U:
1826         {
1827             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(4U);
1828             break;
1829         }
1830         case 25U:
1831         {
1832             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(5U);
1833             break;
1834         }
1835         case 30U:
1836         {
1837             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(6U);
1838             break;
1839         }
1840         case 240U:
1841         {
1842             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(7U);
1843             break;
1844         }
1845         default:
1846         {
1847             retVal = false;
1848             break;
1849         }
1850     }
1851 
1852     if (retVal)
1853     {
1854         /* enable usb phy clock */
1855         CLOCK_EnableClock(kCLOCK_UsbhsPhy);
1856         USBPHY->CTRL_CLR = USBPHY_CTRL_SFTRST_MASK;
1857         USBPHY->CTRL_CLR = USBPHY_CTRL_CLR_CLKGATE_MASK;
1858 
1859         /* This field controls the USB PLL regulator, set to enable the regulator. SW
1860         must set this bit 15 us before setting PLL_POWER to avoid glitches on PLL
1861         output clock. */
1862         USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_PLL_REG_ENABLE_MASK;
1863         uint32_t i          = 5000U;
1864         while ((i--) != 0U)
1865         {
1866             __NOP();
1867         }
1868 
1869         USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_PLL_POWER(1);
1870         while ((USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_POWER_MASK) == 0U)
1871         {
1872             USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_PLL_POWER(1);
1873         }
1874 
1875         while ((USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK) == 0U)
1876         {
1877         }
1878 
1879         USBPHY->PLL_SIC     = (USBPHY->PLL_SIC & ~(USBPHY_PLL_SIC_PLL_DIV_SEL_MASK)) | phyPllDiv;
1880         USBPHY->PLL_SIC_CLR = USBPHY_PLL_SIC_PLL_BYPASS_MASK;
1881         while ((USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_BYPASS_MASK) != 0U)
1882         {
1883             USBPHY->PLL_SIC_CLR = USBPHY_PLL_SIC_PLL_BYPASS_MASK;
1884         }
1885 
1886         USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_PLL_ENABLE(1);
1887         USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_EN_USB_CLKS(1);
1888         while ((USBPHY->PLL_SIC & (USBPHY_PLL_SIC_PLL_ENABLE(1) | USBPHY_PLL_SIC_SET_PLL_EN_USB_CLKS(1))) !=
1889                (USBPHY_PLL_SIC_PLL_ENABLE(1) | USBPHY_PLL_SIC_SET_PLL_EN_USB_CLKS(1)))
1890         {
1891             USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_PLL_ENABLE(1) | USBPHY_PLL_SIC_SET_PLL_EN_USB_CLKS(1);
1892         }
1893 
1894         USBPHY->PWD = 0x0;
1895     }
1896 
1897     return retVal;
1898 }
1899 
1900 /*! @brief Disable USB hs0PhyPll clock.
1901  *
1902  * This function disables USB hs0PhyPll clock.
1903  */
CLOCK_DisableUsbHs0PhyPllClock(void)1904 void CLOCK_DisableUsbHs0PhyPllClock(void)
1905 {
1906     USBPHY->CTRL |= USBPHY_CTRL_CLKGATE_MASK;          /* Set to 1U to gate clocks */
1907     USBPHY->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* Power down PLL */
1908 }
1909