1 /*
2  * Copyright 2021-2022 NXP
3  *
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_clock.h"
9 
10 /*
11  * $Coverage Justification Reference$
12  *
13  * $Justification clock_c_ref_1$
14  * The platform can select only four clock sources.
15  *
16  * $Justification clock_c_ref_2$
17  * After the board starts, the SIRC clock source is always enable and valid.
18  *
19  * $Justification clock_c_ref_3$
20  * During the init FIRC process, the De-init Firc is first performed.
21  * In this process, the successful De-init will Write One to clear the
22  * FIRCERR bit of the FIRCCSR register.And trim, has only two modes to
23  * choose from, and the setting trim mode is always successful.
24  *
25  * $Justification clock_c_ref_4$
26  * After the board starts, the FRO192M output clock is always valid.
27  *
28  */
29 
30 /*******************************************************************************
31  * Definitions
32  ******************************************************************************/
33 /* Component ID definition, used by tools. */
34 #ifndef FSL_COMPONENT_ID
35 #define FSL_COMPONENT_ID "platform.drivers.clock"
36 #endif
37 
38 /*! @brief Slow IRC clock frequency. */
39 #define SCG_SIRC_FREQ 6000000U
40 /*! @brief Get the RANGE value of the Fast IRC. */
41 #define SCG_FIRCCFG_RANGE_VAL ((CLOCK_REG(&SCG0->FIRCCFG) & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT)
42 /*! @brief Get the value of each field in MRCC register. */
43 #define MRCC_MUX_VAL(reg) (((reg)&MRCC_MUX_MASK) >> MRCC_MUX_SHIFT)
44 /*! @brief Get the POSTDIV_SEL value of the FRO192M. */
45 #define FRO192M_FROCCSR_POSTDIV_SEL_VAL \
46     ((CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_POSTDIV_SEL_MASK) >> FRO192M_FROCCSR_POSTDIV_SEL_SHIFT)
47 
48 /*******************************************************************************
49  * Variables
50  ******************************************************************************/
51 
52 /*! @brief External XTAL0 (OSC0) clock frequency. */
53 volatile uint32_t g_xtal0Freq;
54 /*! @brief External XTAL32K clock frequency. */
55 volatile uint32_t g_xtal32Freq;
56 
57 /*******************************************************************************
58  * Prototypes
59  ******************************************************************************/
60 
61 /*******************************************************************************
62  * Code
63  ******************************************************************************/
64 
65 /*!
66  * brief Get the flash clock frequency.
67  *
68  * return Clock frequency in Hz.
69  */
CLOCK_GetFlashClkFreq(void)70 uint32_t CLOCK_GetFlashClkFreq(void)
71 {
72     return CLOCK_GetSysClkFreq(kSCG_SysClkSlow);
73 }
74 
75 /*!
76  * brief Get the bus clock frequency.
77  *
78  * return Clock frequency in Hz.
79  */
CLOCK_GetBusClkFreq(void)80 uint32_t CLOCK_GetBusClkFreq(void)
81 {
82     return CLOCK_GetSysClkFreq(kSCG_SysClkBus);
83 }
84 
85 /*!
86  * brief Get the platform clock frequency.
87  *
88  * return Clock frequency in Hz.
89  */
CLOCK_GetPlatClkFreq(void)90 uint32_t CLOCK_GetPlatClkFreq(void)
91 {
92     return CLOCK_GetSysClkFreq(kSCG_SysClkCore);
93 }
94 
95 /*!
96  * brief Get the core clock or system clock frequency.
97  *
98  * return Clock frequency in Hz.
99  */
CLOCK_GetCoreSysClkFreq(void)100 uint32_t CLOCK_GetCoreSysClkFreq(void)
101 {
102     return CLOCK_GetSysClkFreq(kSCG_SysClkCore);
103 }
104 
105 /*!
106  * brief Gets the clock frequency for a specific clock name.
107  *
108  * This function checks the current clock configurations and then calculates
109  * the clock frequency for a specific clock name defined in clock_name_t.
110  *
111  * param clockName Clock names defined in clock_name_t
112  * return Clock frequency value in hertz
113  */
CLOCK_GetFreq(clock_name_t clockName)114 uint32_t CLOCK_GetFreq(clock_name_t clockName)
115 {
116     uint32_t freq;
117 
118     switch (clockName)
119     {
120         /* System layer clock. */
121         case kCLOCK_CoreSysClk:
122         case kCLOCK_PlatClk:
123             freq = CLOCK_GetSysClkFreq(kSCG_SysClkCore);
124             break;
125         case kCLOCK_BusClk:
126             freq = CLOCK_GetSysClkFreq(kSCG_SysClkBus);
127             break;
128         case kCLOCK_SlowClk:
129             freq = CLOCK_GetSysClkFreq(kSCG_SysClkSlow);
130             break;
131         /* Original clock source. */
132         case kCLOCK_SysClk:
133         case kCLOCK_ScgSysOscClk:
134             freq = CLOCK_GetSysOscFreq();
135             break;
136         case kCLOCK_ScgSircClk:
137             freq = CLOCK_GetSircFreq();
138             break;
139         case kCLOCK_ScgFircClk:
140             freq = CLOCK_GetFircFreq();
141             break;
142         case kCLOCK_RtcOscClk:
143             freq = CLOCK_GetRtcOscFreq();
144             break;
145         default:
146             freq = 0U;
147             break;
148     }
149     return freq;
150 }
151 
152 /*!
153  * brief Gets the functional clock frequency for a specific IP module.
154  *
155  * This function gets the IP module's functional clock frequency based on MRCC
156  * registers. It is only used for the IP modules which could select clock source
157  * by MRCC[MUX].
158  *
159  * param name Which peripheral to get, see \ref clock_ip_name_t.
160  * return Clock frequency value in Hz
161  */
CLOCK_GetIpFreq(clock_ip_name_t name)162 uint32_t CLOCK_GetIpFreq(clock_ip_name_t name)
163 {
164     if (kCLOCK_NOGATE == name)
165     {
166         return 0U;
167     }
168 
169     uint32_t reg = CLOCK_REG(name);
170     uint32_t freq;
171 
172     assert(reg & MRCC_PR_MASK);
173 
174     switch (name)
175     {
176         case kCLOCK_Lpi2c0:
177         case kCLOCK_Lpi2c1:
178         case kCLOCK_I3c0:
179         case kCLOCK_Lpspi0:
180         case kCLOCK_Lpspi1:
181         case kCLOCK_Lpit0:
182         case kCLOCK_Lpadc0:
183         case kCLOCK_Flexio0:
184             switch (MRCC_MUX_VAL(reg))
185             {
186                 case (uint32_t)kCLOCK_IpSrcFro6M:
187                     freq = CLOCK_GetSircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
188                     break;
189                 case (uint32_t)kCLOCK_IpSrcFro192M:
190                     freq = CLOCK_GetFircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
191                     break;
192                 case (uint32_t)kCLOCK_IpSrcSoscClk:
193                     freq = CLOCK_GetSysOscFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
194                     break;
195                 default:
196                     freq = 0U;
197                     break;
198             }
199             break;
200         case kCLOCK_Lpuart0:
201         case kCLOCK_Lpuart1:
202         case kCLOCK_Tpm0:
203         case kCLOCK_Tpm1:
204             switch (MRCC_MUX_VAL(reg))
205             {
206                 case (uint32_t)kCLOCK_IpSrcFro6M:
207                     freq = CLOCK_GetSircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
208                     break;
209                 case (uint32_t)kCLOCK_IpSrcFro192M:
210                     freq = CLOCK_GetFircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
211                     break;
212                 case (uint32_t)kCLOCK_IpSrcSoscClk:
213                     freq = CLOCK_GetSysOscFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
214                     break;
215                 case (uint32_t)kCLOCK_IpSrc32kClk:
216                     freq = CLOCK_GetRtcOscFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
217                     break;
218                 default:
219                     freq = 0U;
220                     break;
221             }
222             break;
223         case kCLOCK_Can0:
224         case kCLOCK_Can1:
225             switch (MRCC_MUX_VAL(reg))
226             {
227                 case (uint32_t)kCLOCK_IpSrcFro192M:
228                     freq = CLOCK_GetFircFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
229                     break;
230                 case (uint32_t)kCLOCK_IpSrcSoscClk:
231                     freq = CLOCK_GetSysOscFreq() / (((reg & MRCC_DIV_MASK) >> MRCC_DIV_SHIFT) + 1U);
232                     break;
233                 default:
234                     freq = 0U;
235                     break;
236             }
237             break;
238         default:
239             freq = 0U;
240             break;
241     }
242 
243     return freq;
244 }
245 
246 /*!
247  * brief Gets the SCG system clock frequency.
248  *
249  * This function gets the SCG system clock frequency. These clocks are used for
250  * core, platform, external, and bus clock domains.
251  *
252  * param type     Which type of clock to get, core clock or slow clock.
253  * return  Clock frequency.
254  */
CLOCK_GetSysClkFreq(scg_sys_clk_t type)255 uint32_t CLOCK_GetSysClkFreq(scg_sys_clk_t type)
256 {
257     uint32_t freq;
258 
259     scg_sys_clk_config_t sysClkConfig;
260 
261     CLOCK_GetCurSysClkConfig(&sysClkConfig); /* Get the main clock for SoC platform. */
262 
263     /*
264      * $Branch Coverage Justification$
265      * ((sysClkConfig.src) != (kSCG_SysClkSrcSysOsc || kSCG_SysClkSrcSirc ||
266      *   kSCG_SysClkSrcFirc || kSCG_SysClkSrcRosc)) not covered.
267      * $ref clock_c_ref_1$.
268      */
269     switch ((scg_sys_clk_src_t)sysClkConfig.src)
270     {
271         case kSCG_SysClkSrcSysOsc:
272             freq = CLOCK_GetSysOscFreq();
273             break;
274         case kSCG_SysClkSrcSirc:
275             freq = CLOCK_GetSircFreq();
276             break;
277         case kSCG_SysClkSrcFirc:
278             freq = CLOCK_GetFircFreq();
279             break;
280         case kSCG_SysClkSrcRosc:
281             freq = CLOCK_GetRtcOscFreq();
282             break;
283         default:
284             freq = 24000000U;
285             break;
286     }
287 
288     freq /= (sysClkConfig.divCore + 1U); /* Divided by the DIVCORE firstly. */
289 
290     switch (type)
291     {
292         case kSCG_SysClkSlow:
293             freq /= (sysClkConfig.divSlow + 1U);
294             break;
295         case kSCG_SysClkBus:
296             freq /= (sysClkConfig.divBus + 1U);
297             break;
298         case kSCG_SysClkPlatform:
299         case kSCG_SysClkCore:
300             break;
301         default:
302             assert(false);
303             break;
304     }
305 
306     return freq;
307 }
308 
309 /*!
310  * brief Initializes the SCG system OSC.
311  *
312  * This function enables the SCG system OSC clock according to the
313  * configuration.
314  *
315  * param config   Pointer to the configuration structure.
316  * retval kStatus_Success System OSC is initialized.
317  * retval kStatus_SCG_Busy System OSC has been enabled and is used by the system clock.
318  * retval kStatus_ReadOnly System OSC control register is locked.
319  *
320  * note This function can't detect whether the system OSC has been enabled and
321  * used by an IP.
322  */
CLOCK_InitSysOsc(const scg_sosc_config_t * config)323 status_t CLOCK_InitSysOsc(const scg_sosc_config_t *config)
324 {
325     assert(config);
326     status_t status;
327 
328     /* De-init the SOSC first. */
329     status = CLOCK_DeinitSysOsc();
330 
331     if (kStatus_Success != status)
332     {
333         return status;
334     }
335 
336     CLOCK_REG(&SCG0->SOSCCSR) = (uint32_t)config->enableMode | SCG_SOSCCSR_SOSCEN_MASK;
337 
338     CLOCK_SetSysOscMonitorMode(config->monitorMode);
339 
340     /* Wait for SOSC clock to be valid. */
341     while ((CLOCK_REG(&SCG0->SOSCCSR) & SCG_SOSCCSR_SOSCVLD_MASK) != SCG_SOSCCSR_SOSCVLD_MASK)
342     {
343     }
344 
345     return (status_t)kStatus_Success;
346 }
347 
348 /*!
349  * brief De-initializes the SCG system OSC.
350  *
351  * This function disables the SCG system OSC clock.
352  *
353  * retval kStatus_Success System OSC is deinitialized.
354  * retval kStatus_SCG_Busy System OSC is used by the system clock.
355  * retval kStatus_ReadOnly System OSC control register is locked.
356  *
357  * note This function can't detect whether the system OSC is used by an IP.
358  */
CLOCK_DeinitSysOsc(void)359 status_t CLOCK_DeinitSysOsc(void)
360 {
361     uint32_t reg = CLOCK_REG(&SCG0->SOSCCSR);
362 
363     /* If clock is used by system, return error. */
364     if ((reg & SCG_SOSCCSR_SOSCSEL_MASK) == SCG_SOSCCSR_SOSCSEL_MASK)
365     {
366         return (status_t)kStatus_SCG_Busy;
367     }
368 
369     /* If configure register is locked, return error. */
370     if ((reg & SCG_SOSCCSR_LK_MASK) == SCG_SOSCCSR_LK_MASK)
371     {
372         return (status_t)kStatus_ReadOnly;
373     }
374 
375     CLOCK_REG(&SCG0->SOSCCSR) = SCG_SOSCCSR_SOSCERR_MASK;
376 
377     return (status_t)kStatus_Success;
378 }
379 
380 /*!
381  * brief Gets the SCG system oscillator clock frequency (SOSC).
382  *
383  * return  Clock frequency; If the clock is invalid, returns 0.
384  */
CLOCK_GetSysOscFreq(void)385 uint32_t CLOCK_GetSysOscFreq(void)
386 {
387     if ((CLOCK_REG(&SCG0->SOSCCSR) & SCG_SOSCCSR_SOSCVLD_MASK) ==
388         SCG_SOSCCSR_SOSCVLD_MASK) /* System OSC clock is valid. */
389     {
390         /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */
391         assert(g_xtal0Freq);
392         return g_xtal0Freq;
393     }
394     else
395     {
396         return 0U;
397     }
398 }
399 
400 /*!
401  * brief Initializes the SCG slow IRC clock.
402  *
403  * This function enables the SCG slow IRC clock according to the
404  * configuration.
405  *
406  * param config   Pointer to the configuration structure.
407  * retval kStatus_Success SIRC is initialized.
408  * retval kStatus_SCG_Busy SIRC has been enabled and is used by system clock.
409  * retval kStatus_ReadOnly SIRC control register is locked.
410  *
411  * note This function can't detect whether the system OSC has been enabled and
412  * used by an IP.
413  */
CLOCK_InitSirc(const scg_sirc_config_t * config)414 status_t CLOCK_InitSirc(const scg_sirc_config_t *config)
415 {
416     assert(config);
417 
418     status_t status;
419 
420     /* De-init the SIRC first. */
421     status = CLOCK_DeinitSirc();
422 
423     if (kStatus_Success != status)
424     {
425         return status;
426     }
427 
428     CLOCK_REG(&SCG0->SIRCCSR) = (uint32_t)config->enableMode;
429 
430     /* Wait for SIRC clock to be valid. */
431 
432     /*
433      * $Branch Coverage Justification$
434      * (CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK) != SCG_SIRCCSR_SIRCVLD_MASK
435      * not covered.
436      * $ref clock_c_ref_2$.
437      */
438     while ((CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK) != SCG_SIRCCSR_SIRCVLD_MASK)
439     {
440     }
441 
442     return (status_t)kStatus_Success;
443 }
444 
445 /*!
446  * brief De-initializes the SCG slow IRC.
447  *
448  * This function disables the SCG slow IRC.
449  *
450  * retval kStatus_Success SIRC is deinitialized.
451  * retval kStatus_SCG_Busy SIRC is used by system clock.
452  * retval kStatus_ReadOnly SIRC control register is locked.
453  *
454  * note This function can't detect whether the SIRC is used by an IP.
455  */
CLOCK_DeinitSirc(void)456 status_t CLOCK_DeinitSirc(void)
457 {
458     uint32_t reg = CLOCK_REG(&SCG0->SIRCCSR);
459 
460     /* If clock is used by system, return error. */
461     if ((reg & SCG_SIRCCSR_SIRCSEL_MASK) == SCG_SIRCCSR_SIRCSEL_MASK)
462     {
463         return (status_t)kStatus_SCG_Busy;
464     }
465 
466     /* If configure register is locked, return error. */
467     if ((reg & SCG_SIRCCSR_LK_MASK) == SCG_SIRCCSR_LK_MASK)
468     {
469         return (status_t)kStatus_ReadOnly;
470     }
471 
472     CLOCK_REG(&SCG0->SIRCCSR) = 0U;
473 
474     return (status_t)kStatus_Success;
475 }
476 
477 /*!
478  * brief Gets the SCG SIRC clock frequency.
479  *
480  * return  Clock frequency; If the clock is invalid, returns 0.
481  */
CLOCK_GetSircFreq(void)482 uint32_t CLOCK_GetSircFreq(void)
483 {
484     /*
485      * $Branch Coverage Justification$
486      * (CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK) != SCG_SIRCCSR_SIRCVLD_MASK
487      * not covered.
488      * $ref clock_c_ref_2$.
489      */
490     if ((CLOCK_REG(&SCG0->SIRCCSR) & SCG_SIRCCSR_SIRCVLD_MASK) == SCG_SIRCCSR_SIRCVLD_MASK) /* SIRC is valid. */
491     {
492         return SCG_SIRC_FREQ;
493     }
494     else
495     {
496         return 0U;
497     }
498 }
499 
500 /*!
501  * brief Initializes the SCG fast IRC clock.
502  *
503  * This function enables the SCG fast IRC clock according to the configuration.
504  *
505  * param config   Pointer to the configuration structure.
506  * retval kStatus_Success FIRC is initialized.
507  * retval kStatus_SCG_Busy FIRC has been enabled and is used by the system clock.
508  * retval kStatus_ReadOnly FIRC control register is locked.
509  *
510  * note This function can't detect whether the FIRC has been enabled and
511  * used by an IP.
512  */
CLOCK_InitFirc(const scg_firc_config_t * config)513 status_t CLOCK_InitFirc(const scg_firc_config_t *config)
514 {
515     assert(config);
516 
517     status_t status;
518 
519     /* De-init the FIRC first. */
520     status = CLOCK_DeinitFirc();
521 
522     if (kStatus_Success != status)
523     {
524         return status;
525     }
526 
527     CLOCK_REG(&SCG0->FIRCCFG) = SCG_FIRCCFG_RANGE(config->range);
528 
529     if (config->trimConfig != NULL)
530     {
531         CLOCK_REG(&SCG0->FIRCTCFG) =
532             SCG_FIRCTCFG_TRIMDIV(config->trimConfig->trimDiv) | SCG_FIRCTCFG_TRIMSRC(config->trimConfig->trimSrc);
533 
534         if (kSCG_FircTrimNonUpdate == config->trimConfig->trimMode)
535         {
536             CLOCK_REG(&SCG0->FIRCSTAT) = SCG_FIRCSTAT_TRIMFINE(config->trimConfig->trimFine);
537         }
538 
539         /* Set trim mode. */
540         CLOCK_REG(&SCG0->FIRCCSR) = (uint32_t)config->trimConfig->trimMode;
541 
542         /*
543          * $Branch Coverage Justification$
544          * (CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCERR_MASK) == SCG_FIRCCSR_FIRCERR_MASK
545          * not covered.
546          * $ref clock_c_ref_3$.
547          */
548         if ((CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCERR_MASK) == SCG_FIRCCSR_FIRCERR_MASK)
549         {
550             return (status_t)kStatus_Fail;
551         }
552     }
553 
554     CLOCK_REG(&SCG0->FIRCCSR) |= (SCG_FIRCCSR_FIRCEN_MASK | (uint32_t)config->enableMode);
555 
556     /* Wait for FIRC clock to be valid. */
557     while ((CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCVLD_MASK) != SCG_FIRCCSR_FIRCVLD_MASK)
558     {
559     }
560 
561     return (status_t)kStatus_Success;
562 }
563 
564 /*!
565  * brief De-initializes the SCG fast IRC.
566  *
567  * This function disables the SCG fast IRC.
568  *
569  * retval kStatus_Success FIRC is deinitialized.
570  * retval kStatus_SCG_Busy FIRC is used by the system clock.
571  * retval kStatus_ReadOnly FIRC control register is locked.
572  *
573  * note This function can't detect whether the FIRC is used by an IP.
574  */
CLOCK_DeinitFirc(void)575 status_t CLOCK_DeinitFirc(void)
576 {
577     uint32_t reg = CLOCK_REG(&SCG0->FIRCCSR);
578 
579     /* If clock is used by system, return error. */
580     if ((reg & SCG_FIRCCSR_FIRCSEL_MASK) == SCG_FIRCCSR_FIRCSEL_MASK)
581     {
582         return (status_t)kStatus_SCG_Busy;
583     }
584 
585     /* If configure register is locked, return error. */
586     if ((reg & SCG_FIRCCSR_LK_MASK) == SCG_FIRCCSR_LK_MASK)
587     {
588         return (status_t)kStatus_ReadOnly;
589     }
590 
591     CLOCK_REG(&SCG0->FIRCCSR) = SCG_FIRCCSR_FIRCERR_MASK;
592 
593     return (status_t)kStatus_Success;
594 }
595 
596 /*!
597  * brief Gets the SCG FIRC clock frequency.
598  *
599  * return  Clock frequency; If the clock is invalid, returns 0.
600  */
CLOCK_GetFircFreq(void)601 uint32_t CLOCK_GetFircFreq(void)
602 {
603     static const uint32_t fircFreq[] = {48000000U, 64000000U, 96000000U, 192000000U};
604 
605     if ((CLOCK_REG(&SCG0->FIRCCSR) & SCG_FIRCCSR_FIRCVLD_MASK) == SCG_FIRCCSR_FIRCVLD_MASK) /* FIRC is valid. */
606     {
607         return fircFreq[SCG_FIRCCFG_RANGE_VAL];
608     }
609     else
610     {
611         return 0U;
612     }
613 }
614 
615 /*!
616  * brief Initializes the SCG ROSC.
617  *
618  * This function enables the SCG ROSC clock according to the
619  * configuration.
620  *
621  * param config   Pointer to the configuration structure.
622  * retval kStatus_Success ROSC is initialized.
623  * retval kStatus_SCG_Busy ROSC has been enabled and is used by the system clock.
624  * retval kStatus_ReadOnly ROSC control register is locked.
625  *
626  * note This function can't detect whether the system OSC has been enabled and
627  * used by an IP.
628  */
CLOCK_InitRosc(const scg_rosc_config_t * config)629 status_t CLOCK_InitRosc(const scg_rosc_config_t *config)
630 {
631     assert(config);
632     status_t status;
633 
634     /* De-init the ROSC first. */
635     status = CLOCK_DeinitRosc();
636 
637     if (kStatus_Success != status)
638     {
639         return status;
640     }
641 
642     CLOCK_SetRoscMonitorMode(config->monitorMode);
643 
644     /* Wait for ROSC clock to be valid. */
645     while ((CLOCK_REG(&SCG0->ROSCCSR) & SCG_ROSCCSR_ROSCVLD_MASK) != SCG_ROSCCSR_ROSCVLD_MASK)
646     {
647     }
648 
649     return (status_t)kStatus_Success;
650 }
651 
652 /*!
653  * brief De-initializes the SCG ROSC.
654  *
655  * This function disables the SCG ROSC clock.
656  *
657  * retval kStatus_Success System OSC is deinitialized.
658  * retval kStatus_SCG_Busy System OSC is used by the system clock.
659  * retval kStatus_ReadOnly System OSC control register is locked.
660  *
661  * note This function can't detect whether the ROSC is used by an IP.
662  */
CLOCK_DeinitRosc(void)663 status_t CLOCK_DeinitRosc(void)
664 {
665     uint32_t reg = CLOCK_REG(&SCG0->ROSCCSR);
666 
667     /* If clock is used by system, return error. */
668     if ((reg & SCG_ROSCCSR_ROSCSEL_MASK) == SCG_ROSCCSR_ROSCSEL_MASK)
669     {
670         return (status_t)kStatus_SCG_Busy;
671     }
672 
673     /* If configure register is locked, return error. */
674     if ((reg & SCG_ROSCCSR_LK_MASK) == SCG_ROSCCSR_LK_MASK)
675     {
676         return (status_t)kStatus_ReadOnly;
677     }
678 
679     CLOCK_REG(&SCG0->ROSCCSR) = SCG_ROSCCSR_ROSCERR_MASK;
680 
681     return (status_t)kStatus_Success;
682 }
683 
684 /*!
685  * @brief Gets the SCG RTC OSC clock frequency.
686  *
687  * @return  Clock frequency; If the clock is invalid, returns 0.
688  */
CLOCK_GetRtcOscFreq(void)689 uint32_t CLOCK_GetRtcOscFreq(void)
690 {
691     if ((CLOCK_REG(&SCG0->ROSCCSR) & SCG_ROSCCSR_ROSCVLD_MASK) ==
692         SCG_ROSCCSR_ROSCVLD_MASK) /* RTC OSC clock is valid. */
693     {
694         /* Please call CLOCK_SetXtal32Freq base on board setting before using RTC OSC clock. */
695         assert(g_xtal32Freq);
696         return g_xtal32Freq;
697     }
698     else
699     {
700         return 0U;
701     }
702 }
703 
704 /*!
705  * @brief Initializes the FRO192M clock for the Radio Mode Controller.
706  *
707  * This function configure the RF FRO192M clock according to the configuration.
708  *
709  * @param config   Pointer to the configuration structure.
710  * @retval kStatus_Success RF FRO192M is configured.
711  */
CLOCK_InitRfFro192M(const fro192m_rf_clk_config_t * config)712 status_t CLOCK_InitRfFro192M(const fro192m_rf_clk_config_t *config)
713 {
714     assert(config->range <= kFro192M_Range64M);
715     assert(config->apb_rfcmc_div <= kFro192M_ClkDivBy8);
716 
717     CLOCK_REG(&FRO192M0->FROCCSR) = FRO192M_FROCCSR_POSTDIV_SEL(config->range);
718     CLOCK_REG(&FRO192M0->FRODIV)  = FRO192M_FRODIV_FRODIV(config->apb_rfcmc_div);
719 
720     /* Wait for RF FRO192M clock to be valid. */
721 
722     /*
723      * $Branch Coverage Justification$
724      * (CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_VALID_MASK) != FRO192M_FROCCSR_VALID_MASK
725      * not covered.
726      * $ref clock_c_ref_4$.
727      */
728     while ((CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_VALID_MASK) != FRO192M_FROCCSR_VALID_MASK)
729     {
730     }
731 
732     return (status_t)kStatus_Success;
733 }
734 
735 /*!
736  * @brief Gets the FRO192M clock frequency.
737  *
738  * @return  Clock frequency; If the clock is invalid, returns 0.
739  */
CLOCK_GetRfFro192MFreq(void)740 uint32_t CLOCK_GetRfFro192MFreq(void)
741 {
742     static const uint32_t fro192mFreq[] = {16000000U, 24000000U, 32000000U, 48000000U, 64000000U};
743 
744     /*
745      * $Branch Coverage Justification$
746      * (CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_VALID_MASK) != FRO192M_FROCCSR_VALID_MASK
747      * not covered.
748      * $ref clock_c_ref_4$.
749      */
750     if ((CLOCK_REG(&FRO192M0->FROCCSR) & FRO192M_FROCCSR_VALID_MASK) == FRO192M_FROCCSR_VALID_MASK)
751     {
752         return fro192mFreq[FRO192M_FROCCSR_POSTDIV_SEL_VAL];
753     }
754     else
755     {
756         return 0U;
757     }
758 }
759