1 /*
2  * Copyright 2017 - 2021 , NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_clock.h"
9 #include "fsl_power.h"
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "platform.drivers.clock"
16 #endif
17 #define NVALMAX (0x100U)
18 #define PVALMAX (0x20U)
19 #define MVALMAX (0x10000U)
20 
21 #define PLL_MAX_N_DIV 0x100U
22 
23 /*--------------------------------------------------------------------------
24 !!! If required these #defines can be moved to chip library file
25 ----------------------------------------------------------------------------*/
26 
27 #define PLL_SSCG1_MDEC_VAL_P (10U) /* MDEC is in bits  25 downto 10 */
28 #define PLL_SSCG1_MDEC_VAL_M (0xFFFFULL << PLL_SSCG1_MDEC_VAL_P)
29 #define PLL_NDEC_VAL_P       (0U) /* NDEC is in bits  9:0 */
30 #define PLL_NDEC_VAL_M       (0xFFUL << PLL_NDEC_VAL_P)
31 #define PLL_PDEC_VAL_P       (0U) /*!<  PDEC is in bits 6:0 */
32 #define PLL_PDEC_VAL_M       (0x1FUL << PLL_PDEC_VAL_P)
33 
34 #define PLL_MIN_CCO_FREQ_MHZ (275000000U)
35 #define PLL_MAX_CCO_FREQ_MHZ (550000000U)
36 #define PLL_LOWER_IN_LIMIT   (2000U)      /*!<  Minimum PLL input rate */
37 #define PLL_HIGHER_IN_LIMIT  (150000000U) /*!<  Maximum PLL input rate */
38 #define PLL_MIN_IN_SSMODE    (3000000U)
39 #define PLL_MAX_IN_SSMODE \
40     (100000000U) /*!<  Not find the value in UM, Just use the maximum frequency which device support */
41 
42 /* PLL NDEC reg */
43 #define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
44 /* PLL PDEC reg */
45 #define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
46 /* SSCG control1 */
47 #define PLL_SSCG1_MDEC_VAL_SET(value) (((uint64_t)(value) << PLL_SSCG1_MDEC_VAL_P) & PLL_SSCG1_MDEC_VAL_M)
48 
49 /* PLL0 SSCG control1 */
50 #define PLL0_SSCG_MD_FRACT_P 0U
51 #define PLL0_SSCG_MD_INT_P   25U
52 #define PLL0_SSCG_MD_FRACT_M (0x1FFFFFFUL << PLL0_SSCG_MD_FRACT_P)
53 #define PLL0_SSCG_MD_INT_M   ((uint64_t)0xFFUL << PLL0_SSCG_MD_INT_P)
54 
55 #define PLL0_SSCG_MD_FRACT_SET(value) (((uint64_t)(value) << PLL0_SSCG_MD_FRACT_P) & PLL0_SSCG_MD_FRACT_M)
56 #define PLL0_SSCG_MD_INT_SET(value)   (((uint64_t)(value) << PLL0_SSCG_MD_INT_P) & PLL0_SSCG_MD_INT_M)
57 
58 /* Saved value of PLL output rate, computed whenever needed to save run-time
59    computation on each call to retrive the PLL rate. */
60 static uint32_t s_Pll0_Freq;
61 static uint32_t s_Pll1_Freq;
62 
63 /** External clock rate on the CLKIN pin in Hz. If not used,
64     set this to 0. Otherwise, set it to the exact rate in Hz this pin is
65     being driven at. */
66 static uint32_t s_Ext_Clk_Freq   = 16000000U;
67 static uint32_t s_I2S_Mclk_Freq  = 0U;
68 static uint32_t s_PLU_ClkIn_Freq = 0U;
69 
70 /*******************************************************************************
71  * Variables
72  ******************************************************************************/
73 
74 /*******************************************************************************
75  * Prototypes
76  ******************************************************************************/
77 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
78 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR);
79 /* Get predivider (N) from PLL0 NDEC setting */
80 static uint32_t findPll0PreDiv(void);
81 /* Get predivider (N) from PLL1 NDEC setting */
82 static uint32_t findPll1PreDiv(void);
83 /* Get postdivider (P) from PLL0 PDEC setting */
84 static uint32_t findPll0PostDiv(void);
85 /* Get postdivider (P) from PLL1 PDEC setting. */
86 static uint32_t findPll1PostDiv(void);
87 /* Get multiplier (M) from PLL0 MDEC and SSCG settings */
88 static float findPll0MMult(void);
89 /* Get multiplier (M) from PLL1 MDEC. */
90 static uint32_t findPll1MMult(void);
91 /* Get the greatest common divisor */
92 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n);
93 /* Set PLL output based on desired output rate */
94 static pll_error_t CLOCK_GetPll0Config(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS);
95 /* Update local PLL rate variable */
96 static void CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t *pSetup);
97 /* Update local PLL1 rate variable */
98 static void CLOCK_GetPLL1OutFromSetupUpdate(pll_setup_t *pSetup);
99 
100 /*******************************************************************************
101  * Code
102  ******************************************************************************/
103 
104 /* Clock Selection for IP */
105 /**
106  * brief   Configure the clock selection muxes.
107  * param   connection  : Clock to be configured.
108  * return  Nothing
109  */
CLOCK_AttachClk(clock_attach_id_t connection)110 void CLOCK_AttachClk(clock_attach_id_t connection)
111 {
112     uint8_t mux;
113     uint8_t sel;
114     uint16_t item;
115     uint32_t tmp32 = (uint32_t)connection;
116     uint32_t i;
117     volatile uint32_t *pClkSel;
118 
119     pClkSel = &(SYSCON->SYSTICKCLKSELX[0]);
120 
121     if (kNONE_to_NONE != connection)
122     {
123         for (i = 0U; i < 2U; i++)
124         {
125             if (tmp32 == 0U)
126             {
127                 break;
128             }
129             item = (uint16_t)GET_ID_ITEM(tmp32);
130             if (item != 0U)
131             {
132                 mux = (uint8_t)GET_ID_ITEM_MUX(item);
133                 sel = (uint8_t)GET_ID_ITEM_SEL(item);
134                 if (mux == CM_RTCOSC32KCLKSEL)
135                 {
136                     PMC->RTCOSC32K = (PMC->RTCOSC32K & ~PMC_RTCOSC32K_SEL_MASK) | PMC_RTCOSC32K_SEL(sel);
137                 }
138                 else if (mux == CM_OSTIMERCLKSEL)
139                 {
140                     PMC->OSTIMERr = (PMC->OSTIMERr & ~PMC_OSTIMER_OSTIMERCLKSEL_MASK) | PMC_OSTIMER_OSTIMERCLKSEL(sel);
141                 }
142                 else
143                 {
144                     pClkSel[mux] = sel;
145                 }
146             }
147             tmp32 = GET_ID_NEXT_ITEM(tmp32); /* pick up next descriptor */
148         }
149     }
150 }
151 
152 /* Return the actual clock attach id */
153 /**
154  * brief   Get the actual clock attach id.
155  * This fuction uses the offset in input attach id, then it reads the actual source value in
156  * the register and combine the offset to obtain an actual attach id.
157  * param   attachId  : Clock attach id to get.
158  * return  Clock source value.
159  */
CLOCK_GetClockAttachId(clock_attach_id_t attachId)160 clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId)
161 {
162     uint8_t mux;
163     uint32_t actualSel;
164     uint32_t tmp32 = (uint32_t)attachId;
165     uint32_t i;
166     uint32_t actualAttachId = 0U;
167     uint32_t selector       = GET_ID_SELECTOR(tmp32);
168     volatile uint32_t *pClkSel;
169 
170     pClkSel = &(SYSCON->SYSTICKCLKSELX[0]);
171 
172     if (kNONE_to_NONE == attachId)
173     {
174         return kNONE_to_NONE;
175     }
176 
177     for (i = 0U; i < 2U; i++)
178     {
179         mux = (uint8_t)GET_ID_ITEM_MUX(tmp32);
180         if (tmp32 != 0UL)
181         {
182             if (mux == CM_RTCOSC32KCLKSEL)
183             {
184                 actualSel = ((PMC->RTCOSC32K) & PMC_RTCOSC32K_SEL_MASK) >> PMC_RTCOSC32K_SEL_SHIFT;
185             }
186             else if (mux == CM_OSTIMERCLKSEL)
187             {
188                 actualSel = ((PMC->OSTIMERr) & PMC_OSTIMER_OSTIMERCLKSEL_MASK) >> PMC_OSTIMER_OSTIMERCLKSEL_SHIFT;
189             }
190             else
191             {
192                 actualSel = pClkSel[mux];
193             }
194 
195             /* Consider the combination of two registers */
196             actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i);
197         }
198         tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!<  pick up next descriptor */
199     }
200 
201     actualAttachId |= selector;
202 
203     return (clock_attach_id_t)actualAttachId;
204 }
205 
206 /* Set IP Clock Divider */
207 /**
208  * brief   Setup peripheral clock dividers.
209  * param   div_name    : Clock divider name
210  * param divided_by_value: Value to be divided
211  * param reset :  Whether to reset the divider counter.
212  * return  Nothing
213  */
CLOCK_SetClkDiv(clock_div_name_t div_name,uint32_t divided_by_value,bool reset)214 void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
215 {
216     volatile uint32_t *pClkDiv;
217 
218     pClkDiv = &(SYSCON->SYSTICKCLKDIV0);
219     if ((div_name >= kCLOCK_DivFlexFrg0) && (div_name <= kCLOCK_DivFlexFrg7))
220     {
221         /*!<  Flexcomm Interface function clock = (clock selected via FCCLKSEL) / (1+ MULT /DIV), DIV = 0xFF */
222         ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] =
223             SYSCON_FLEXFRG0CTRL_DIV_MASK | SYSCON_FLEXFRG0CTRL_MULT(divided_by_value);
224     }
225     else
226     {
227         if (reset)
228         {
229             ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 29U;
230         }
231         if (divided_by_value == 0U) /*!<  halt */
232         {
233             ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 30U;
234         }
235         else
236         {
237             ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = (divided_by_value - 1U);
238         }
239     }
240 }
241 
242 /* Set RTC 1KHz Clock Divider */
243 /**
244  * brief   Setup rtc 1khz clock divider.
245  * param divided_by_value: Value to be divided
246  * return  Nothing
247  */
CLOCK_SetRtc1khzClkDiv(uint32_t divided_by_value)248 void CLOCK_SetRtc1khzClkDiv(uint32_t divided_by_value)
249 {
250     PMC->RTCOSC32K =
251         (PMC->RTCOSC32K & ~PMC_RTCOSC32K_CLK1KHZDIV_MASK) | PMC_RTCOSC32K_CLK1KHZDIV(divided_by_value - 28U);
252 }
253 
254 /* Set RTC 1KHz Clock Divider */
255 /**
256  * brief   Setup rtc 1hz clock divider.
257  * param divided_by_value: Value to be divided
258  * return  Nothing
259  */
CLOCK_SetRtc1hzClkDiv(uint32_t divided_by_value)260 void CLOCK_SetRtc1hzClkDiv(uint32_t divided_by_value)
261 {
262     if (divided_by_value == 0U) /*!<  halt */
263     {
264         PMC->RTCOSC32K |= (1UL << PMC_RTCOSC32K_CLK1HZDIVHALT_SHIFT);
265     }
266     else
267     {
268         PMC->RTCOSC32K =
269             (PMC->RTCOSC32K & ~PMC_RTCOSC32K_CLK1HZDIV_MASK) | PMC_RTCOSC32K_CLK1HZDIV(divided_by_value - 31744U);
270     }
271 }
272 
273 /* Set FRO Clocking */
274 /**
275  * brief   Initialize the Core clock to given frequency (12, 48 or 96 MHz).
276  * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is
277  * enabled.
278  * param   iFreq   : Desired frequency (must be one of #CLK_FRO_12MHZ or #CLK_FRO_48MHZ or #CLK_FRO_96MHZ)
279  * return  returns success or fail status.
280  */
CLOCK_SetupFROClocking(uint32_t iFreq)281 status_t CLOCK_SetupFROClocking(uint32_t iFreq)
282 {
283     if ((iFreq != 12000000U) && (iFreq != 96000000U))
284     {
285         return kStatus_Fail;
286     }
287     /* Enable Analog Control module */
288     SYSCON->PRESETCTRLCLR[2] = (1UL << SYSCON_PRESETCTRL2_ANALOG_CTRL_RST_SHIFT);
289     SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_ANALOG_CTRL_MASK;
290     /* Power up the FRO192M */
291     POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
292 
293     if (iFreq == 96000000U)
294     {
295         ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_96MHZCLK(1);
296     }
297     /* always enable
298     else if (iFreq == 48000000U)
299     {
300         ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_48MHZCLK(1);
301     }*/
302     else
303     {
304         ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_ENA_12MHZCLK(1);
305     }
306     return kStatus_Success;
307 }
308 
309 /* Set the FLASH wait states for the passed frequency */
310 /**
311  * brief    Set the flash wait states for the input freuqency.
312  * param    iFreq: Input frequency
313  * return    Nothing
314  */
315 typedef struct
316 {
317     uint32_t waitstate;
318     uint32_t freqMax;
319 } WaitStateInterval_t;
320 
321 /* clang-format off */
322 /* Wait state if frequency is inferior to the one specified */
323 static const WaitStateInterval_t IntervalList[] = {
324     {0, 11000000},
325     {1, 22000000},
326     {2, 33000000},
327     {3, 44000000},
328     {4, 55000000},
329     {5, 66000000},
330     {6, 84000000},
331     {7, 104000000},
332     {8, 119000000},
333     {9, 129000000},
334     {10, 144000000},
335     {11, 150000000} /* Maximum allowed frequency (150 MHz) */
336 };
337 /* clang-format on */
338 
CLOCK_SetFLASHAccessCyclesForFreq(uint32_t system_freq_hz)339 void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t system_freq_hz)
340 {
341     /* Flash Controller & FMC internal number of Wait States (minus 1) */
342     uint32_t num_wait_states      = 15UL; /* Default to the maximum number of wait states */
343     uint32_t prefetch_enable_mask = SYSCON->FMCCR & SYSCON_FMCCR_PREFEN_MASK;
344 
345     for (size_t cnt = 0; cnt < (sizeof(IntervalList) / sizeof(WaitStateInterval_t)); cnt++)
346     {
347         if (system_freq_hz <= IntervalList[cnt].freqMax)
348         {
349             num_wait_states = IntervalList[cnt].waitstate;
350             break;
351         }
352     }
353 
354     /*The prefetch bit must be disabled before any flash commands*/
355     SYSCON->FMCCR &= ~SYSCON_FMCCR_PREFEN_MASK;
356 
357     FLASH->INT_CLR_STATUS = 0x1F; /* Clear all status flags */
358 
359     FLASH->DATAW[0] = (FLASH->DATAW[0] & 0xFFFFFFF0UL) |
360                       (num_wait_states & (SYSCON_FMCCR_FLASHTIM_MASK >> SYSCON_FMCCR_FLASHTIM_SHIFT));
361 
362     FLASH->CMD = 0x2; /* CMD_SET_READ_MODE */
363 
364     /* Wait until the cmd is completed (without error) */
365     while ((FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK) == 0UL)
366     {
367     }
368 
369     /* Adjust FMC waiting time cycles (num_wait_states) */
370     SYSCON->FMCCR = (SYSCON->FMCCR & ~SYSCON_FMCCR_FLASHTIM_MASK) |
371                     ((num_wait_states << SYSCON_FMCCR_FLASHTIM_SHIFT) & SYSCON_FMCCR_FLASHTIM_MASK);
372 
373     /* restore prefetch enable */
374     SYSCON->FMCCR |= prefetch_enable_mask;
375 }
376 
377 /* Set EXT OSC Clk */
378 /**
379  * brief   Initialize the external osc clock to given frequency.
380  * Crystal oscillator with an operating frequency of 12 MHz to 32 MHz.
381  * Option for external clock input (bypass mode) for clock frequencies of up to 25 MHz.
382  * param   iFreq   : Desired frequency (must be equal to exact rate in Hz)
383  * return  returns success or fail status.
384  */
CLOCK_SetupExtClocking(uint32_t iFreq)385 status_t CLOCK_SetupExtClocking(uint32_t iFreq)
386 {
387     if (iFreq > 32000000U)
388     {
389         return kStatus_Fail;
390     }
391     /* Turn on power for crystal 32 MHz */
392     POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
393     POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
394     /* Enable clock_in clock for clock module. */
395     SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK;
396 
397     /* Wait for external osc clock to be valid. */
398     while((ANACTRL->XO32M_STATUS & ANACTRL_XO32M_STATUS_XO_READY_MASK) == 0U)
399     {
400     }
401 
402     s_Ext_Clk_Freq = iFreq;
403     return kStatus_Success;
404 }
405 
406 /* Set I2S MCLK Clk */
407 /**
408  * brief   Initialize the I2S MCLK clock to given frequency.
409  * param   iFreq   : Desired frequency (must be equal to exact rate in Hz)
410  * return  returns success or fail status.
411  */
CLOCK_SetupI2SMClkClocking(uint32_t iFreq)412 status_t CLOCK_SetupI2SMClkClocking(uint32_t iFreq)
413 {
414     s_I2S_Mclk_Freq = iFreq;
415     return kStatus_Success;
416 }
417 
418 /* Set PLU CLKIN Clk */
419 /**
420  * brief   Initialize the PLU CLKIN clock to given frequency.
421  * param   iFreq   : Desired frequency (must be equal to exact rate in Hz)
422  * return  returns success or fail status.
423  */
CLOCK_SetupPLUClkInClocking(uint32_t iFreq)424 status_t CLOCK_SetupPLUClkInClocking(uint32_t iFreq)
425 {
426     s_PLU_ClkIn_Freq = iFreq;
427     return kStatus_Success;
428 }
429 
430 /* Get CLOCK OUT Clk */
431 /*! brief  Return Frequency of ClockOut
432  *  return Frequency of ClockOut
433  */
CLOCK_GetClockOutClkFreq(void)434 uint32_t CLOCK_GetClockOutClkFreq(void)
435 {
436     uint32_t freq = 0U;
437 
438     switch (SYSCON->CLKOUTSEL)
439     {
440         case 0U:
441             freq = CLOCK_GetCoreSysClkFreq();
442             break;
443 
444         case 1U:
445             freq = CLOCK_GetPll0OutFreq();
446             break;
447 
448         case 2U:
449             freq = CLOCK_GetExtClkFreq();
450             break;
451 
452         case 3U:
453             freq = CLOCK_GetFroHfFreq();
454             break;
455 
456         case 4U:
457             freq = CLOCK_GetFro1MFreq();
458             break;
459 
460         case 5U:
461             freq = CLOCK_GetPll1OutFreq();
462             break;
463 
464         case 6U:
465             freq = CLOCK_GetOsc32KFreq();
466             break;
467 
468         case 7U:
469             freq = 0U;
470             break;
471 
472         default:
473             freq = 0U;
474             break;
475     }
476     return freq / ((SYSCON->CLKOUTDIV & 0xffU) + 1U);
477 }
478 
479 /* Get CAN Clk */
480 /*! brief  Return Frequency of Can Clock
481  *  return Frequency of Can.
482  */
CLOCK_GetMCanClkFreq(void)483 uint32_t CLOCK_GetMCanClkFreq(void)
484 {
485     uint32_t freq = 0U;
486 
487     switch (SYSCON->CANCLKSEL)
488     {
489         case 0U:
490             freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->CANCLKDIV & SYSCON_CANCLKDIV_DIV_MASK) + 1U);
491             break;
492         case 1U:
493             freq = CLOCK_GetFro1MFreq();
494             break;
495         case 2U:
496             freq = CLOCK_GetOsc32KFreq();
497             break;
498         case 7U:
499             freq = 0U;
500             break;
501 
502         default:
503             freq = 0U;
504             break;
505     }
506 
507     return freq;
508 }
509 
510 /* Get ADC Clk */
511 /*! brief  Return Frequency of Adc Clock
512  *  return Frequency of Adc.
513  */
CLOCK_GetAdcClkFreq(void)514 uint32_t CLOCK_GetAdcClkFreq(void)
515 {
516     uint32_t freq = 0U;
517 
518     switch (SYSCON->ADCCLKSEL)
519     {
520         case 0U:
521             freq = CLOCK_GetCoreSysClkFreq();
522             break;
523         case 1U:
524             freq = CLOCK_GetPll0OutFreq();
525             break;
526         case 2U:
527             freq = CLOCK_GetFroHfFreq();
528             break;
529         case 7U:
530             freq = 0U;
531             break;
532 
533         default:
534             freq = 0U;
535             break;
536     }
537 
538     return freq / ((SYSCON->ADCCLKDIV & SYSCON_ADCCLKDIV_DIV_MASK) + 1U);
539 }
540 
541 /* Get USB0 Clk */
542 /*! brief  Return Frequency of Usb0 Clock
543  *  return Frequency of Usb0 Clock.
544  */
CLOCK_GetUsb0ClkFreq(void)545 uint32_t CLOCK_GetUsb0ClkFreq(void)
546 {
547     uint32_t freq = 0U;
548 
549     switch (SYSCON->USB0CLKSEL)
550     {
551         case 0U:
552             freq = CLOCK_GetCoreSysClkFreq();
553             break;
554         case 1U:
555             freq = CLOCK_GetPll0OutFreq();
556             break;
557         case 3U:
558             freq = CLOCK_GetFroHfFreq();
559             break;
560         case 5U:
561             freq = CLOCK_GetPll1OutFreq();
562             break;
563         case 7U:
564             freq = 0U;
565             break;
566 
567         default:
568             freq = 0U;
569             break;
570     }
571 
572     return freq / ((SYSCON->USB0CLKDIV & 0xffU) + 1U);
573 }
574 
575 /* Get USB1 Clk */
576 /*! brief  Return Frequency of Usb1 Clock
577  *  return Frequency of Usb1 Clock.
578  */
CLOCK_GetUsb1ClkFreq(void)579 uint32_t CLOCK_GetUsb1ClkFreq(void)
580 {
581     return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT_MASK) != 0UL) ? s_Ext_Clk_Freq : 0U;
582 }
583 
584 /* Get MCLK Clk */
585 /*! brief  Return Frequency of MClk Clock
586  *  return Frequency of MClk Clock.
587  */
CLOCK_GetMclkClkFreq(void)588 uint32_t CLOCK_GetMclkClkFreq(void)
589 {
590     uint32_t freq = 0U;
591 
592     switch (SYSCON->MCLKCLKSEL)
593     {
594         case 0U:
595             freq = CLOCK_GetFroHfFreq();
596             break;
597         case 1U:
598             freq = CLOCK_GetPll0OutFreq();
599             break;
600         case 7U:
601             freq = 0U;
602             break;
603 
604         default:
605             freq = 0U;
606             break;
607     }
608 
609     return freq / ((SYSCON->MCLKDIV & 0xffU) + 1U);
610 }
611 
612 /* Get SCTIMER Clk */
613 /*! brief  Return Frequency of SCTimer Clock
614  *  return Frequency of SCTimer Clock.
615  */
CLOCK_GetSctClkFreq(void)616 uint32_t CLOCK_GetSctClkFreq(void)
617 {
618     uint32_t freq = 0U;
619 
620     switch (SYSCON->SCTCLKSEL)
621     {
622         case 0U:
623             freq = CLOCK_GetCoreSysClkFreq();
624             break;
625         case 1U:
626             freq = CLOCK_GetPll0OutFreq();
627             break;
628         case 2U:
629             freq = CLOCK_GetExtClkFreq();
630             break;
631         case 3U:
632             freq = CLOCK_GetFroHfFreq();
633             break;
634         case 5U:
635             freq = CLOCK_GetI2SMClkFreq();
636             break;
637         case 7U:
638             freq = 0U;
639             break;
640 
641         default:
642             freq = 0U;
643             break;
644     }
645 
646     return freq / ((SYSCON->SCTCLKDIV & 0xffU) + 1U);
647 }
648 
649 /* Get FRO 12M Clk */
650 /*! brief  Return Frequency of FRO 12MHz
651  *  return Frequency of FRO 12MHz
652  */
CLOCK_GetFro12MFreq(void)653 uint32_t CLOCK_GetFro12MFreq(void)
654 {
655     return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK) != 0UL) ? 12000000U : 0U;
656 }
657 
658 /* Get FRO 1M Clk */
659 /*! brief  Return Frequency of FRO 1MHz
660  *  return Frequency of FRO 1MHz
661  */
CLOCK_GetFro1MFreq(void)662 uint32_t CLOCK_GetFro1MFreq(void)
663 {
664     return ((SYSCON->CLOCK_CTRL & SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK) != 0UL) ? 1000000U : 0U;
665 }
666 
667 /* Get EXT OSC Clk */
668 /*! brief  Return Frequency of External Clock
669  *  return Frequency of External Clock. If no external clock is used returns 0.
670  */
CLOCK_GetExtClkFreq(void)671 uint32_t CLOCK_GetExtClkFreq(void)
672 {
673     return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK) != 0UL) ? s_Ext_Clk_Freq : 0U;
674 }
675 
676 /* Get WATCH DOG Clk */
677 /*! brief  Return Frequency of Watchdog
678  *  return Frequency of Watchdog
679  */
CLOCK_GetWdtClkFreq(void)680 uint32_t CLOCK_GetWdtClkFreq(void)
681 {
682     return CLOCK_GetFro1MFreq() / ((SYSCON->WDTCLKDIV & SYSCON_WDTCLKDIV_DIV_MASK) + 1U);
683 }
684 
685 /* Get HF FRO Clk */
686 /*! brief  Return Frequency of High-Freq output of FRO
687  *  return Frequency of High-Freq output of FRO
688  */
CLOCK_GetFroHfFreq(void)689 uint32_t CLOCK_GetFroHfFreq(void)
690 {
691     return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK) != 0UL) ? 96000000U : 0U;
692 }
693 
694 /* Get SYSTEM PLL Clk */
695 /*! brief  Return Frequency of PLL
696  *  return Frequency of PLL
697  */
CLOCK_GetPll0OutFreq(void)698 uint32_t CLOCK_GetPll0OutFreq(void)
699 {
700     return s_Pll0_Freq;
701 }
702 
703 /* Get USB PLL Clk */
704 /*! brief  Return Frequency of USB PLL
705  *  return Frequency of PLL
706  */
CLOCK_GetPll1OutFreq(void)707 uint32_t CLOCK_GetPll1OutFreq(void)
708 {
709     return s_Pll1_Freq;
710 }
711 
712 /* Get RTC OSC Clk */
713 /*! brief  Return Frequency of 32kHz osc
714  *  return Frequency of 32kHz osc
715  */
CLOCK_GetOsc32KFreq(void)716 uint32_t CLOCK_GetOsc32KFreq(void)
717 {
718     return ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_FRO32K_MASK)) &&
719             (0UL == (PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK))) ?
720                CLK_RTC_32K_CLK :
721                ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_XTAL32K_MASK)) &&
722                 ((PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK) != 0UL)) ?
723                CLK_RTC_32K_CLK :
724                0UL;
725 }
726 
727 /* Get MAIN Clk */
728 /*! brief  Return Frequency of Core System
729  *  return Frequency of Core System
730  */
CLOCK_GetCoreSysClkFreq(void)731 uint32_t CLOCK_GetCoreSysClkFreq(void)
732 {
733     uint32_t freq = 0U;
734 
735     switch (SYSCON->MAINCLKSELB)
736     {
737         case 0U:
738             if (SYSCON->MAINCLKSELA == 0U)
739             {
740                 freq = CLOCK_GetFro12MFreq();
741             }
742             else if (SYSCON->MAINCLKSELA == 1U)
743             {
744                 freq = CLOCK_GetExtClkFreq();
745             }
746             else if (SYSCON->MAINCLKSELA == 2U)
747             {
748                 freq = CLOCK_GetFro1MFreq();
749             }
750             else if (SYSCON->MAINCLKSELA == 3U)
751             {
752                 freq = CLOCK_GetFroHfFreq();
753             }
754             else
755             {
756                 /* Added comments to avoid the violation of MISRA C-2012 rule 15.7 */
757             }
758             break;
759         case 1U:
760             freq = CLOCK_GetPll0OutFreq();
761             break;
762         case 2U:
763             freq = CLOCK_GetPll1OutFreq();
764             break;
765 
766         case 3U:
767             freq = CLOCK_GetOsc32KFreq();
768             break;
769 
770         default:
771             freq = 0U;
772             break;
773     }
774 
775     return freq;
776 }
777 
778 /* Get I2S MCLK Clk */
779 /*! brief  Return Frequency of I2S MCLK Clock
780  *  return Frequency of I2S MCLK Clock
781  */
CLOCK_GetI2SMClkFreq(void)782 uint32_t CLOCK_GetI2SMClkFreq(void)
783 {
784     return s_I2S_Mclk_Freq;
785 }
786 
787 /* Get PLU CLKIN Clk */
788 /*! brief  Return Frequency of PLU CLKIN Clock
789  *  return Frequency of PLU CLKIN Clock
790  */
CLOCK_GetPLUClkInFreq(void)791 uint32_t CLOCK_GetPLUClkInFreq(void)
792 {
793     return s_PLU_ClkIn_Freq;
794 }
795 
796 /* Get FLEXCOMM input clock */
797 /*! brief  Return Frequency of flexcomm input clock
798  *  param  id     : flexcomm instance id
799  *  return Frequency value
800  */
CLOCK_GetFlexCommInputClock(uint32_t id)801 uint32_t CLOCK_GetFlexCommInputClock(uint32_t id)
802 {
803     uint32_t freq = 0U;
804 
805     switch (SYSCON->FCCLKSELX[id])
806     {
807         case 0U:
808             freq = CLOCK_GetCoreSysClkFreq();
809             break;
810         case 1U:
811             freq = CLOCK_GetPll0OutFreq() / ((SYSCON->PLL0CLKDIV & 0xffU) + 1U);
812             break;
813         case 2U:
814             freq = CLOCK_GetFro12MFreq();
815             break;
816         case 3U:
817             freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffU) + 1U);
818             break;
819         case 4U:
820             freq = CLOCK_GetFro1MFreq();
821             break;
822         case 5U:
823             freq = CLOCK_GetI2SMClkFreq();
824             break;
825         case 6U:
826             freq = CLOCK_GetOsc32KFreq();
827             break;
828         case 7U:
829             freq = 0U;
830             break;
831 
832         default:
833             freq = 0U;
834             break;
835     }
836 
837     return freq;
838 }
839 
840 /* Get FLEXCOMM Clk */
CLOCK_GetFlexCommClkFreq(uint32_t id)841 uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
842 {
843     uint32_t freq   = 0U;
844     uint32_t frgMul = 0U;
845     uint32_t frgDiv = 0U;
846 
847     freq   = CLOCK_GetFlexCommInputClock(id);
848     frgMul = (SYSCON->FLEXFRGXCTRL[id] & SYSCON_FLEXFRG0CTRL_MULT_MASK) >> 8U;
849     frgDiv = SYSCON->FLEXFRGXCTRL[id] & SYSCON_FLEXFRG0CTRL_DIV_MASK;
850     return (uint32_t)(((uint64_t)freq * ((uint64_t)frgDiv + 1ULL)) / (frgMul + frgDiv + 1UL));
851 }
852 
853 /* Get HS_LPSI Clk */
CLOCK_GetHsLspiClkFreq(void)854 uint32_t CLOCK_GetHsLspiClkFreq(void)
855 {
856     uint32_t freq = 0U;
857 
858     switch (SYSCON->HSLSPICLKSEL)
859     {
860         case 0U:
861             freq = CLOCK_GetCoreSysClkFreq();
862             break;
863         case 1U:
864             freq = CLOCK_GetPll0OutFreq() / ((SYSCON->PLL0CLKDIV & 0xffU) + 1U);
865             break;
866         case 2U:
867             freq = CLOCK_GetFro12MFreq();
868             break;
869         case 3U:
870             freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffU) + 1U);
871             break;
872         case 4U:
873             freq = CLOCK_GetFro1MFreq();
874             break;
875         case 6U:
876             freq = CLOCK_GetOsc32KFreq();
877             break;
878         case 7U:
879             freq = 0U;
880             break;
881 
882         default:
883             freq = 0U;
884             break;
885     }
886 
887     return freq;
888 }
889 
890 /* Get CTimer Clk */
891 /*! brief  Return Frequency of CTimer functional Clock
892  *  return Frequency of CTimer functional Clock
893  */
CLOCK_GetCTimerClkFreq(uint32_t id)894 uint32_t CLOCK_GetCTimerClkFreq(uint32_t id)
895 {
896     uint32_t freq = 0U;
897 
898     switch (SYSCON->CTIMERCLKSELX[id])
899     {
900         case 0U:
901             freq = CLOCK_GetCoreSysClkFreq();
902             break;
903         case 1U:
904             freq = CLOCK_GetPll0OutFreq();
905             break;
906         case 3U:
907             freq = CLOCK_GetFroHfFreq();
908             break;
909         case 4U:
910             freq = CLOCK_GetFro1MFreq();
911             break;
912         case 5U:
913             freq = CLOCK_GetI2SMClkFreq();
914             break;
915         case 6U:
916             freq = CLOCK_GetOsc32KFreq();
917             break;
918         case 7U:
919             freq = 0U;
920             break;
921 
922         default:
923             freq = 0U;
924             break;
925     }
926 
927     return freq;
928 }
929 
930 /* Get Systick Clk */
931 /*! brief  Return Frequency of SystickClock
932  *  return Frequency of Systick Clock
933  */
CLOCK_GetSystickClkFreq(uint32_t id)934 uint32_t CLOCK_GetSystickClkFreq(uint32_t id)
935 {
936     uint32_t freq = 0U;
937 
938     switch (SYSCON->SYSTICKCLKSELX[id])
939     {
940         case 0U:
941             /*Niobe4mini just has one SYSTICKSEL and SYSTICKDIV register, Fix coverity problem in this way temporarily
942              */
943             freq = CLOCK_GetCoreSysClkFreq() / (((SYSCON->SYSTICKCLKDIV0) & 0xffU) + 1U);
944             break;
945         case 1U:
946             freq = CLOCK_GetFro1MFreq();
947             break;
948         case 2U:
949             freq = CLOCK_GetOsc32KFreq();
950             break;
951         case 7U:
952             freq = 0U;
953             break;
954 
955         default:
956             freq = 0U;
957             break;
958     }
959 
960     return freq;
961 }
962 
963 /* Set FlexComm Clock */
964 /**
965  * brief   Set the flexcomm output frequency.
966  * param   id      : flexcomm instance id
967  *          freq    : output frequency
968  * return  0   : the frequency range is out of range.
969  *          1   : switch successfully.
970  */
CLOCK_SetFlexCommClock(uint32_t id,uint32_t freq)971 uint32_t CLOCK_SetFlexCommClock(uint32_t id, uint32_t freq)
972 {
973     uint32_t input = CLOCK_GetFlexCommClkFreq(id);
974     uint32_t mul;
975 
976     if ((freq > 48000000UL) || (freq > input) || (input / freq >= 2UL))
977     {
978         /* FRG output frequency should be less than equal to 48MHz */
979         return 0UL;
980     }
981     else
982     {
983         mul                      = (uint32_t)((((uint64_t)input - freq) * 256ULL) / ((uint64_t)freq));
984         SYSCON->FLEXFRGXCTRL[id] = (mul << 8U) | 0xFFU;
985         return 1UL;
986     }
987 }
988 
989 /* Get IP Clk */
990 /*! brief  Return Frequency of selected clock
991  *  return Frequency of selected clock
992  */
CLOCK_GetFreq(clock_name_t clockName)993 uint32_t CLOCK_GetFreq(clock_name_t clockName)
994 {
995     uint32_t freq;
996     switch (clockName)
997     {
998         case kCLOCK_CoreSysClk:
999             freq = CLOCK_GetCoreSysClkFreq();
1000             break;
1001         case kCLOCK_BusClk:
1002             freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
1003             break;
1004         case kCLOCK_ClockOut:
1005             freq = CLOCK_GetClockOutClkFreq();
1006             break;
1007         case kCLOCK_Pll1Out:
1008             freq = CLOCK_GetPll1OutFreq();
1009             break;
1010         case kCLOCK_Mclk:
1011             freq = CLOCK_GetMclkClkFreq();
1012             break;
1013         case kCLOCK_FroHf:
1014             freq = CLOCK_GetFroHfFreq();
1015             break;
1016         case kCLOCK_Fro12M:
1017             freq = CLOCK_GetFro12MFreq();
1018             break;
1019         case kCLOCK_Fro1M:
1020             freq = CLOCK_GetFro1MFreq();
1021             break;
1022         case kCLOCK_ExtClk:
1023             freq = CLOCK_GetExtClkFreq();
1024             break;
1025         case kCLOCK_Pll0Out:
1026             freq = CLOCK_GetPll0OutFreq();
1027             break;
1028         case kCLOCK_FlexI2S:
1029             freq = CLOCK_GetI2SMClkFreq();
1030             break;
1031         default:
1032             freq = 0U;
1033             break;
1034     }
1035     return freq;
1036 }
1037 
1038 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
pllFindSel(uint32_t M,uint32_t * pSelP,uint32_t * pSelI,uint32_t * pSelR)1039 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
1040 {
1041     uint32_t seli, selp;
1042     /* bandwidth: compute selP from Multiplier */
1043     if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL) /* normal mode */
1044     {
1045         selp = (M >> 2U) + 1U;
1046         if (selp >= 31U)
1047         {
1048             selp = 31U;
1049         }
1050         *pSelP = selp;
1051 
1052         if (M >= 8000UL)
1053         {
1054             seli = 1UL;
1055         }
1056         else if (M >= 122UL)
1057         {
1058             seli = (uint32_t)(8000UL / M); /*floor(8000/M) */
1059         }
1060         else
1061         {
1062             seli = 2UL * ((uint32_t)(M / 4UL)) + 3UL; /* 2*floor(M/4) + 3 */
1063         }
1064 
1065         if (seli >= 63UL)
1066         {
1067             seli = 63UL;
1068         }
1069         *pSelI = seli;
1070 
1071         *pSelR = 0UL;
1072     }
1073     else
1074     {
1075         /* Note: If the spread spectrum mode, choose N to ensure 3 MHz < Fin/N < 5 MHz */
1076         *pSelP = 3U;
1077         *pSelI = 4U;
1078         *pSelR = 4U;
1079     }
1080 }
1081 
1082 /* Get predivider (N) from PLL0 NDEC setting */
findPll0PreDiv(void)1083 static uint32_t findPll0PreDiv(void)
1084 {
1085     uint32_t preDiv = 1UL;
1086 
1087     /* Direct input is not used? */
1088     if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPREDIV_MASK) == 0UL)
1089     {
1090         preDiv = SYSCON->PLL0NDEC & SYSCON_PLL0NDEC_NDIV_MASK;
1091         if (preDiv == 0UL)
1092         {
1093             preDiv = 1UL;
1094         }
1095     }
1096     return preDiv;
1097 }
1098 
1099 /* Get predivider (N) from PLL1 NDEC setting */
findPll1PreDiv(void)1100 static uint32_t findPll1PreDiv(void)
1101 {
1102     uint32_t preDiv = 1UL;
1103 
1104     /* Direct input is not used? */
1105     if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPREDIV_MASK) == 0UL)
1106     {
1107         preDiv = SYSCON->PLL1NDEC & SYSCON_PLL1NDEC_NDIV_MASK;
1108         if (preDiv == 0UL)
1109         {
1110             preDiv = 1UL;
1111         }
1112     }
1113     return preDiv;
1114 }
1115 
1116 /* Get postdivider (P) from PLL0 PDEC setting */
findPll0PostDiv(void)1117 static uint32_t findPll0PostDiv(void)
1118 {
1119     uint32_t postDiv = 1UL;
1120 
1121     if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPOSTDIV_MASK) == 0UL)
1122     {
1123         if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPOSTDIV2_MASK) != 0UL)
1124         {
1125             postDiv = SYSCON->PLL0PDEC & SYSCON_PLL0PDEC_PDIV_MASK;
1126         }
1127         else
1128         {
1129             postDiv = 2UL * (SYSCON->PLL0PDEC & SYSCON_PLL0PDEC_PDIV_MASK);
1130         }
1131         if (postDiv == 0UL)
1132         {
1133             postDiv = 2UL;
1134         }
1135     }
1136     return postDiv;
1137 }
1138 
1139 /* Get postdivider (P) from PLL1 PDEC setting. */
findPll1PostDiv(void)1140 static uint32_t findPll1PostDiv(void)
1141 {
1142     uint32_t postDiv = 1UL;
1143 
1144     if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPOSTDIV_MASK) == 0UL)
1145     {
1146         if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPOSTDIV2_MASK) != 0UL)
1147         {
1148             postDiv = SYSCON->PLL1PDEC & SYSCON_PLL1PDEC_PDIV_MASK;
1149         }
1150         else
1151         {
1152             postDiv = 2UL * (SYSCON->PLL1PDEC & SYSCON_PLL1PDEC_PDIV_MASK);
1153         }
1154         if (postDiv == 0UL)
1155         {
1156             postDiv = 2UL;
1157         }
1158     }
1159 
1160     return postDiv;
1161 }
1162 
1163 /* Get multiplier (M) from PLL0 SSCG and SEL_EXT settings */
findPll0MMult(void)1164 static float findPll0MMult(void)
1165 {
1166     float mMult = 1.0F;
1167     float mMult_fract;
1168     uint32_t mMult_int;
1169 
1170     if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL)
1171     {
1172         mMult =
1173             (float)(uint32_t)((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) >> SYSCON_PLL0SSCG1_MDIV_EXT_SHIFT);
1174     }
1175     else
1176     {
1177         mMult_int   = ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MD_MBS_MASK) << 7U);
1178         mMult_int   = mMult_int | ((SYSCON->PLL0SSCG0) >> PLL0_SSCG_MD_INT_P);
1179         mMult_fract = ((float)(uint32_t)((SYSCON->PLL0SSCG0) & PLL0_SSCG_MD_FRACT_M) /
1180                        (float)(uint32_t)(1UL << PLL0_SSCG_MD_INT_P));
1181         mMult       = (float)mMult_int + mMult_fract;
1182     }
1183     if (0ULL == ((uint64_t)mMult))
1184     {
1185         mMult = 1.0F;
1186     }
1187     return mMult;
1188 }
1189 
1190 /* Get multiplier (M) from PLL1 MDEC. */
findPll1MMult(void)1191 static uint32_t findPll1MMult(void)
1192 {
1193     uint32_t mMult = 1UL;
1194 
1195     mMult = SYSCON->PLL1MDEC & SYSCON_PLL1MDEC_MDIV_MASK;
1196 
1197     if (mMult == 0UL)
1198     {
1199         mMult = 1UL;
1200     }
1201 
1202     return mMult;
1203 }
1204 
1205 /* Find greatest common divisor between m and n */
FindGreatestCommonDivisor(uint32_t m,uint32_t n)1206 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
1207 {
1208     uint32_t tmp;
1209 
1210     while (n != 0U)
1211     {
1212         tmp = n;
1213         n   = m % n;
1214         m   = tmp;
1215     }
1216 
1217     return m;
1218 }
1219 
1220 /*
1221  * Set PLL0 output based on desired output rate.
1222  * In this function, the it calculates the PLL0 setting for output frequency from input clock
1223  * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
1224  * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
1225  */
CLOCK_GetPll0ConfigInternal(uint32_t finHz,uint32_t foutHz,pll_setup_t * pSetup,bool useSS)1226 static pll_error_t CLOCK_GetPll0ConfigInternal(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS)
1227 {
1228     uint32_t nDivOutHz, fccoHz;
1229     uint32_t pllPreDivider, pllMultiplier, pllPostDivider;
1230     uint32_t pllDirectInput, pllDirectOutput;
1231     uint32_t pllSelP, pllSelI, pllSelR, uplimoff;
1232 
1233     /* Baseline parameters (no input or output dividers) */
1234     pllPreDivider   = 1U; /* 1 implies pre-divider will be disabled */
1235     pllPostDivider  = 1U; /* 1 implies post-divider will be disabled */
1236     pllDirectOutput = 1U;
1237 
1238     /* Verify output rate parameter */
1239     if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
1240     {
1241         /* Maximum PLL output with post divider=1 cannot go above this frequency */
1242         return kStatus_PLL_OutputTooHigh;
1243     }
1244     if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
1245     {
1246         /* Minmum PLL output with maximum post divider cannot go below this frequency */
1247         return kStatus_PLL_OutputTooLow;
1248     }
1249 
1250     /* If using SS mode, input clock needs to be between 3MHz and 20MHz */
1251     if (useSS)
1252     {
1253         /* Verify input rate parameter */
1254         if (finHz < PLL_MIN_IN_SSMODE)
1255         {
1256             /* Input clock into the PLL cannot be lower than this */
1257             return kStatus_PLL_InputTooLow;
1258         }
1259         /* PLL input in SS mode must be under 20MHz */
1260         if (finHz > (PLL_MAX_IN_SSMODE * NVALMAX))
1261         {
1262             return kStatus_PLL_InputTooHigh;
1263         }
1264     }
1265     else
1266     {
1267         /* Verify input rate parameter */
1268         if (finHz < PLL_LOWER_IN_LIMIT)
1269         {
1270             /* Input clock into the PLL cannot be lower than this */
1271             return kStatus_PLL_InputTooLow;
1272         }
1273         if (finHz > PLL_HIGHER_IN_LIMIT)
1274         {
1275             /* Input clock into the PLL cannot be higher than this */
1276             return kStatus_PLL_InputTooHigh;
1277         }
1278     }
1279 
1280     /* Find the optimal CCO frequency for the output and input that
1281        will keep it inside the PLL CCO range. This may require
1282        tweaking the post-divider for the PLL. */
1283     fccoHz = foutHz;
1284     while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
1285     {
1286         /* CCO output is less than minimum CCO range, so the CCO output
1287            needs to be bumped up and the post-divider is used to bring
1288            the PLL output back down. */
1289         pllPostDivider++;
1290         if (pllPostDivider > PVALMAX)
1291         {
1292             return kStatus_PLL_OutsideIntLimit;
1293         }
1294 
1295         /* Target CCO goes up, PLL output goes down */
1296         /* divide-by-2 divider in the post-divider is always work*/
1297         fccoHz          = foutHz * (pllPostDivider * 2U);
1298         pllDirectOutput = 0U;
1299     }
1300 
1301     /* Determine if a pre-divider is needed to get the best frequency */
1302     if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz) && (useSS == false))
1303     {
1304         uint32_t a = FindGreatestCommonDivisor(fccoHz, finHz);
1305 
1306         if (a > PLL_LOWER_IN_LIMIT)
1307         {
1308             a = finHz / a;
1309             if ((a != 0U) && (a < PLL_MAX_N_DIV))
1310             {
1311                 pllPreDivider = a;
1312             }
1313         }
1314     }
1315 
1316     /* Bypass pre-divider hardware if pre-divider is 1 */
1317     if (pllPreDivider > 1U)
1318     {
1319         pllDirectInput = 0U;
1320     }
1321     else
1322     {
1323         pllDirectInput = 1U;
1324     }
1325 
1326     /* Determine PLL multipler */
1327     nDivOutHz     = (finHz / pllPreDivider);
1328     pllMultiplier = (fccoHz / nDivOutHz);
1329 
1330     /* Find optimal values for filter */
1331     if (useSS == false)
1332     {
1333         /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
1334         if ((nDivOutHz * ((pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
1335         {
1336             pllMultiplier++;
1337         }
1338 
1339         /* Setup filtering */
1340         pllFindSel(pllMultiplier, &pllSelP, &pllSelI, &pllSelR);
1341         uplimoff = 0U;
1342 
1343         /* Get encoded value for M (mult) and use manual filter, disable SS mode */
1344         pSetup->pllsscg[1] =
1345             (uint32_t)((PLL_SSCG1_MDEC_VAL_SET(pllMultiplier)) | (1UL << SYSCON_PLL0SSCG1_SEL_EXT_SHIFT));
1346     }
1347     else
1348     {
1349         uint64_t fc;
1350 
1351         /* Filtering will be handled by SSC */
1352         pllSelR  = 0UL;
1353         pllSelI  = 0UL;
1354         pllSelP  = 0UL;
1355         uplimoff = 1U;
1356 
1357         /* The PLL multiplier will get very close and slightly under the
1358            desired target frequency. A small fractional component can be
1359            added to fine tune the frequency upwards to the target. */
1360         fc = ((uint64_t)(uint32_t)(fccoHz % nDivOutHz) << 25UL) / nDivOutHz;
1361 
1362         /* Set multiplier */
1363         pSetup->pllsscg[0] = (uint32_t)(PLL0_SSCG_MD_INT_SET(pllMultiplier) | PLL0_SSCG_MD_FRACT_SET((uint32_t)fc));
1364         pSetup->pllsscg[1] = (uint32_t)(PLL0_SSCG_MD_INT_SET(pllMultiplier) >> 32U);
1365     }
1366 
1367     /* Get encoded values for N (prediv) and P (postdiv) */
1368     pSetup->pllndec = PLL_NDEC_VAL_SET(pllPreDivider);
1369     pSetup->pllpdec = PLL_PDEC_VAL_SET(pllPostDivider);
1370 
1371     /* PLL control */
1372     pSetup->pllctrl = (pllSelR << SYSCON_PLL0CTRL_SELR_SHIFT) |                  /* Filter coefficient */
1373                       (pllSelI << SYSCON_PLL0CTRL_SELI_SHIFT) |                  /* Filter coefficient */
1374                       (pllSelP << SYSCON_PLL0CTRL_SELP_SHIFT) |                  /* Filter coefficient */
1375                       (0UL << SYSCON_PLL0CTRL_BYPASSPLL_SHIFT) |                 /* PLL bypass mode disabled */
1376                       (uplimoff << SYSCON_PLL0CTRL_LIMUPOFF_SHIFT) |             /* SS/fractional mode disabled */
1377                       (pllDirectInput << SYSCON_PLL0CTRL_BYPASSPREDIV_SHIFT) |   /* Bypass pre-divider? */
1378                       (pllDirectOutput << SYSCON_PLL0CTRL_BYPASSPOSTDIV_SHIFT) | /* Bypass post-divider? */
1379                       (1UL << SYSCON_PLL0CTRL_CLKEN_SHIFT);                      /* Ensure the PLL clock output */
1380 
1381     return kStatus_PLL_Success;
1382 }
1383 
1384 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1385 /* Alloct the static buffer for cache. */
1386 static pll_setup_t s_PllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
1387 static uint32_t s_FinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT]  = {0};
1388 static uint32_t s_FoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
1389 static bool s_UseSSCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT]      = {false};
1390 static uint32_t s_PllSetupCacheIdx                                  = 0U;
1391 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1392 
1393 /*
1394  * Calculate the PLL setting values from input clock freq to output freq.
1395  */
CLOCK_GetPll0Config(uint32_t finHz,uint32_t foutHz,pll_setup_t * pSetup,bool useSS)1396 static pll_error_t CLOCK_GetPll0Config(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useSS)
1397 {
1398     pll_error_t retErr;
1399 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1400     uint32_t i;
1401 
1402     for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
1403     {
1404         if ((finHz == s_FinHzCache[i]) && (foutHz == s_FoutHzCache[i]) && (useSS == s_UseSSCache[i]))
1405         {
1406             /* Hit the target in cache buffer. */
1407             pSetup->pllctrl    = s_PllSetupCacheStruct[i].pllctrl;
1408             pSetup->pllndec    = s_PllSetupCacheStruct[i].pllndec;
1409             pSetup->pllpdec    = s_PllSetupCacheStruct[i].pllpdec;
1410             pSetup->pllsscg[0] = s_PllSetupCacheStruct[i].pllsscg[0];
1411             pSetup->pllsscg[1] = s_PllSetupCacheStruct[i].pllsscg[1];
1412             retErr             = kStatus_PLL_Success;
1413             break;
1414         }
1415     }
1416 
1417     if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1418     {
1419         return retErr;
1420     }
1421 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1422 
1423     retErr = CLOCK_GetPll0ConfigInternal(finHz, foutHz, pSetup, useSS);
1424 
1425 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1426     /* Cache the most recent calulation result into buffer. */
1427     s_FinHzCache[s_PllSetupCacheIdx]  = finHz;
1428     s_FoutHzCache[s_PllSetupCacheIdx] = foutHz;
1429     s_UseSSCache[s_PllSetupCacheIdx]  = useSS;
1430 
1431     s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllctrl    = pSetup->pllctrl;
1432     s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllndec    = pSetup->pllndec;
1433     s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllpdec    = pSetup->pllpdec;
1434     s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllsscg[0] = pSetup->pllsscg[0];
1435     s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllsscg[1] = pSetup->pllsscg[1];
1436     /* Update the index for next available buffer. */
1437     s_PllSetupCacheIdx = (s_PllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
1438 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1439 
1440     return retErr;
1441 }
1442 
1443 /* Update local PLL rate variable */
CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t * pSetup)1444 static void CLOCK_GetPLL0OutFromSetupUpdate(pll_setup_t *pSetup)
1445 {
1446     s_Pll0_Freq = CLOCK_GetPLL0OutFromSetup(pSetup);
1447 }
1448 
1449 /* Update local PLL1 rate variable */
CLOCK_GetPLL1OutFromSetupUpdate(pll_setup_t * pSetup)1450 static void CLOCK_GetPLL1OutFromSetupUpdate(pll_setup_t *pSetup)
1451 {
1452     s_Pll1_Freq = CLOCK_GetPLL1OutFromSetup(pSetup);
1453 }
1454 
1455 /* Return System PLL input clock rate */
1456 /*! brief    Return  PLL0 input clock rate
1457  *  return    PLL0 input clock rate
1458  */
CLOCK_GetPLL0InClockRate(void)1459 uint32_t CLOCK_GetPLL0InClockRate(void)
1460 {
1461     uint32_t clkRate = 0U;
1462 
1463     switch ((SYSCON->PLL0CLKSEL & SYSCON_PLL0CLKSEL_SEL_MASK))
1464     {
1465         case 0x00U:
1466             clkRate = CLK_FRO_12MHZ;
1467             break;
1468 
1469         case 0x01U:
1470             clkRate = CLOCK_GetExtClkFreq();
1471             break;
1472 
1473         case 0x02U:
1474             clkRate = CLOCK_GetFro1MFreq();
1475             break;
1476 
1477         case 0x03U:
1478             clkRate = CLOCK_GetOsc32KFreq();
1479             break;
1480 
1481         default:
1482             clkRate = 0U;
1483             break;
1484     }
1485 
1486     return clkRate;
1487 }
1488 
1489 /* Return PLL1 input clock rate */
CLOCK_GetPLL1InClockRate(void)1490 uint32_t CLOCK_GetPLL1InClockRate(void)
1491 {
1492     uint32_t clkRate = 0U;
1493 
1494     switch ((SYSCON->PLL1CLKSEL & SYSCON_PLL1CLKSEL_SEL_MASK))
1495     {
1496         case 0x00U:
1497             clkRate = CLK_FRO_12MHZ;
1498             break;
1499 
1500         case 0x01U:
1501             clkRate = CLOCK_GetExtClkFreq();
1502             break;
1503 
1504         case 0x02U:
1505             clkRate = CLOCK_GetFro1MFreq();
1506             break;
1507 
1508         case 0x03U:
1509             clkRate = CLOCK_GetOsc32KFreq();
1510             break;
1511 
1512         default:
1513             clkRate = 0U;
1514             break;
1515     }
1516 
1517     return clkRate;
1518 }
1519 
1520 /* Return PLL0 output clock rate from setup structure */
1521 /*! brief    Return PLL0 output clock rate from setup structure
1522  *  param    pSetup : Pointer to a PLL setup structure
1523  *  return   PLL0 output clock rate the setup structure will generate
1524  */
CLOCK_GetPLL0OutFromSetup(pll_setup_t * pSetup)1525 uint32_t CLOCK_GetPLL0OutFromSetup(pll_setup_t *pSetup)
1526 {
1527     uint32_t clkRate = 0;
1528     uint32_t prediv, postdiv;
1529     float workRate = 0.0F;
1530 
1531     /* Get the input clock frequency of PLL. */
1532     clkRate = CLOCK_GetPLL0InClockRate();
1533 
1534     if (((pSetup->pllctrl & SYSCON_PLL0CTRL_BYPASSPLL_MASK) == 0UL) &&
1535         ((pSetup->pllctrl & SYSCON_PLL0CTRL_CLKEN_MASK) != 0UL) &&
1536         ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_MASK) == 0UL) &&
1537         ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_SSCG_MASK) == 0UL))
1538     {
1539         prediv  = findPll0PreDiv();
1540         postdiv = findPll0PostDiv();
1541         /* Adjust input clock */
1542         clkRate = clkRate / prediv;
1543         /* MDEC used for rate */
1544         workRate = (float)clkRate * (float)findPll0MMult();
1545         workRate /= (float)postdiv;
1546     }
1547 
1548     return (uint32_t)workRate;
1549 }
1550 
1551 /* Return PLL1 output clock rate from setup structure */
1552 /*! brief    Return PLL1 output clock rate from setup structure
1553  *  param    pSetup : Pointer to a PLL setup structure
1554  *  return   PLL0 output clock rate the setup structure will generate
1555  */
CLOCK_GetPLL1OutFromSetup(pll_setup_t * pSetup)1556 uint32_t CLOCK_GetPLL1OutFromSetup(pll_setup_t *pSetup)
1557 {
1558     uint32_t clkRate = 0;
1559     uint32_t prediv, postdiv;
1560     uint32_t workRate = 0UL;
1561 
1562     /* Get the input clock frequency of PLL. */
1563     clkRate = CLOCK_GetPLL1InClockRate();
1564 
1565     if (((pSetup->pllctrl & SYSCON_PLL1CTRL_BYPASSPLL_MASK) == 0UL) &&
1566         ((pSetup->pllctrl & SYSCON_PLL1CTRL_CLKEN_MASK) != 0UL) &&
1567         ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL1_MASK) == 0UL))
1568     {
1569         prediv  = findPll1PreDiv();
1570         postdiv = findPll1PostDiv();
1571         /* Adjust input clock */
1572         clkRate = clkRate / prediv;
1573         /* MDEC used for rate */
1574         workRate = clkRate * findPll1MMult();
1575         workRate /= postdiv;
1576     }
1577 
1578     return workRate;
1579 }
1580 
1581 /* Set the current PLL0 Rate */
1582 /*! brief Store the current PLL rate
1583  *  param    rate: Current rate of the PLL
1584  *  return   Nothing
1585  **/
CLOCK_SetStoredPLL0ClockRate(uint32_t rate)1586 void CLOCK_SetStoredPLL0ClockRate(uint32_t rate)
1587 {
1588     s_Pll0_Freq = rate;
1589 }
1590 
1591 /* Return PLL0 output clock rate */
1592 /*! brief    Return  PLL0 output clock rate
1593  *  param    recompute   : Forces a PLL rate recomputation if true
1594  *  return    PLL0 output clock rate
1595  *  note The PLL rate is cached in the driver in a variable as
1596  *  the rate computation function can take some time to perform. It
1597  *  is recommended to use 'false' with the 'recompute' parameter.
1598  */
CLOCK_GetPLL0OutClockRate(bool recompute)1599 uint32_t CLOCK_GetPLL0OutClockRate(bool recompute)
1600 {
1601     pll_setup_t Setup;
1602     uint32_t rate;
1603 
1604     if ((recompute) || (s_Pll0_Freq == 0U))
1605     {
1606         Setup.pllctrl    = SYSCON->PLL0CTRL;
1607         Setup.pllndec    = SYSCON->PLL0NDEC;
1608         Setup.pllpdec    = SYSCON->PLL0PDEC;
1609         Setup.pllsscg[0] = SYSCON->PLL0SSCG0;
1610         Setup.pllsscg[1] = SYSCON->PLL0SSCG1;
1611 
1612         CLOCK_GetPLL0OutFromSetupUpdate(&Setup);
1613     }
1614 
1615     rate = s_Pll0_Freq;
1616 
1617     return rate;
1618 }
1619 
1620 /*! brief    Return  PLL1 output clock rate
1621  *  param    recompute   : Forces a PLL rate recomputation if true
1622  *  return    PLL1 output clock rate
1623  *  note The PLL rate is cached in the driver in a variable as
1624  *  the rate computation function can take some time to perform. It
1625  *  is recommended to use 'false' with the 'recompute' parameter.
1626  */
CLOCK_GetPLL1OutClockRate(bool recompute)1627 uint32_t CLOCK_GetPLL1OutClockRate(bool recompute)
1628 {
1629     pll_setup_t Setup;
1630     uint32_t rate;
1631 
1632     if ((recompute) || (s_Pll1_Freq == 0U))
1633     {
1634         Setup.pllctrl = SYSCON->PLL1CTRL;
1635         Setup.pllndec = SYSCON->PLL1NDEC;
1636         Setup.pllpdec = SYSCON->PLL1PDEC;
1637         Setup.pllmdec = SYSCON->PLL1MDEC;
1638         CLOCK_GetPLL1OutFromSetupUpdate(&Setup);
1639     }
1640 
1641     rate = s_Pll1_Freq;
1642 
1643     return rate;
1644 }
1645 
1646 /* Set PLL0 output based on the passed PLL setup data */
1647 /*! brief    Set PLL output based on the passed PLL setup data
1648  *  param    pControl    : Pointer to populated PLL control structure to generate setup with
1649  *  param    pSetup      : Pointer to PLL setup structure to be filled
1650  *  return   PLL_ERROR_SUCCESS on success, or PLL setup error code
1651  *  note Actual frequency for setup may vary from the desired frequency based on the
1652  *  accuracy of input clocks, rounding, non-fractional PLL mode, etc.
1653  */
CLOCK_SetupPLL0Data(pll_config_t * pControl,pll_setup_t * pSetup)1654 pll_error_t CLOCK_SetupPLL0Data(pll_config_t *pControl, pll_setup_t *pSetup)
1655 {
1656     uint32_t inRate;
1657     bool useSS = (bool)((pControl->flags & PLL_CONFIGFLAG_FORCENOFRACT) == 0UL);
1658 
1659     pll_error_t pllError;
1660 
1661     /* Determine input rate for the PLL */
1662     if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0UL)
1663     {
1664         inRate = pControl->inputRate;
1665     }
1666     else
1667     {
1668         inRate = CLOCK_GetPLL0InClockRate();
1669     }
1670 
1671     /* PLL flag options */
1672     pllError = CLOCK_GetPll0Config(inRate, pControl->desiredRate, pSetup, useSS);
1673     if ((useSS) && (pllError == kStatus_PLL_Success))
1674     {
1675         /* If using SS mode, then some tweaks are made to the generated setup */
1676         pSetup->pllsscg[1] |= (uint32_t)pControl->ss_mf | (uint32_t)pControl->ss_mr | (uint32_t)pControl->ss_mc;
1677         if (pControl->mfDither)
1678         {
1679             pSetup->pllsscg[1] |= (1UL << SYSCON_PLL0SSCG1_DITHER_SHIFT);
1680         }
1681     }
1682 
1683     return pllError;
1684 }
1685 
1686 /* Set PLL0 output from PLL setup structure */
1687 /*! brief    Set PLL output from PLL setup structure (precise frequency)
1688  * param pSetup  : Pointer to populated PLL setup structure
1689  * param flagcfg : Flag configuration for PLL config structure
1690  * return    PLL_ERROR_SUCCESS on success, or PLL setup error code
1691  * note  This function will power off the PLL, setup the PLL with the
1692  * new setup data, and then optionally powerup the PLL, wait for PLL lock,
1693  * and adjust system voltages to the new PLL rate. The function will not
1694  * alter any source clocks (ie, main systen clock) that may use the PLL,
1695  * so these should be setup prior to and after exiting the function.
1696  */
CLOCK_SetupPLL0Prec(pll_setup_t * pSetup,uint32_t flagcfg)1697 pll_error_t CLOCK_SetupPLL0Prec(pll_setup_t *pSetup, uint32_t flagcfg)
1698 {
1699     uint32_t inRate, clkRate, prediv;
1700     uint32_t pll_lock_wait_time     = 0U;
1701     uint32_t max_pll_lock_wait_time = 0U;
1702     /* Power off PLL during setup changes */
1703     POWER_EnablePD(kPDRUNCFG_PD_PLL0);
1704     POWER_EnablePD(kPDRUNCFG_PD_PLL0_SSCG);
1705 
1706     pSetup->flags = flagcfg;
1707 
1708     /* Write PLL setup data */
1709     SYSCON->PLL0CTRL  = pSetup->pllctrl;
1710     SYSCON->PLL0NDEC  = pSetup->pllndec;
1711     SYSCON->PLL0NDEC  = pSetup->pllndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT); /* latch */
1712     SYSCON->PLL0PDEC  = pSetup->pllpdec;
1713     SYSCON->PLL0PDEC  = pSetup->pllpdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT); /* latch */
1714     SYSCON->PLL0SSCG0 = pSetup->pllsscg[0];
1715     SYSCON->PLL0SSCG1 = pSetup->pllsscg[1];
1716     SYSCON->PLL0SSCG1 =
1717         pSetup->pllsscg[1] | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT) | (1UL << SYSCON_PLL0SSCG1_MD_REQ_SHIFT); /* latch */
1718 
1719     POWER_DisablePD(kPDRUNCFG_PD_PLL0);
1720     POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
1721 
1722     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0UL)
1723     {
1724         if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL) /* normal mode */
1725         {
1726             inRate = CLOCK_GetPLL0InClockRate();
1727             prediv = findPll0PreDiv();
1728             /* Adjust input clock */
1729             clkRate = inRate / prediv;
1730 
1731             /* Need wait at least (500us + 400/Fref) (Fref in Hz result in s) to ensure the PLL is stable.
1732                The lock bit could be used to shorten the wait time when freq<20MHZ */
1733             max_pll_lock_wait_time = 500U + (400000000U / clkRate);
1734 
1735             if (clkRate < 20000000UL)
1736             {
1737                 pll_lock_wait_time = 0U;
1738                 while ((CLOCK_IsPLL0Locked() == false) && (pll_lock_wait_time < max_pll_lock_wait_time))
1739                 {
1740                     pll_lock_wait_time += 100U;
1741                     SDK_DelayAtLeastUs(100U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1742                 }
1743             }
1744             else
1745             {
1746                 SDK_DelayAtLeastUs(max_pll_lock_wait_time, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1747             }
1748         }
1749         else /* spread spectrum mode */
1750         {
1751             SDK_DelayAtLeastUs(6000U,
1752                                SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval to
1753                                                                            insure the PLL will be stable */
1754         }
1755     }
1756 
1757     /* Update current programmed PLL rate var */
1758     CLOCK_GetPLL0OutFromSetupUpdate(pSetup);
1759 
1760     /* System voltage adjustment, occurs prior to setting main system clock */
1761     if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0UL)
1762     {
1763         POWER_SetVoltageForFreq(s_Pll0_Freq);
1764     }
1765 
1766     return kStatus_PLL_Success;
1767 }
1768 
1769 /* Setup PLL Frequency from pre-calculated value */
1770 /**
1771  * brief Set PLL0 output from PLL setup structure (precise frequency)
1772  * param pSetup  : Pointer to populated PLL setup structure
1773  * return    kStatus_PLL_Success on success, or PLL setup error code
1774  * note  This function will power off the PLL, setup the PLL with the
1775  * new setup data, and then optionally powerup the PLL, wait for PLL lock,
1776  * and adjust system voltages to the new PLL rate. The function will not
1777  * alter any source clocks (ie, main systen clock) that may use the PLL,
1778  * so these should be setup prior to and after exiting the function.
1779  */
CLOCK_SetPLL0Freq(const pll_setup_t * pSetup)1780 pll_error_t CLOCK_SetPLL0Freq(const pll_setup_t *pSetup)
1781 {
1782     uint32_t inRate, clkRate, prediv;
1783     uint32_t pll_lock_wait_time     = 0U;
1784     uint32_t max_pll_lock_wait_time = 0U;
1785     /* Power off PLL during setup changes */
1786     POWER_EnablePD(kPDRUNCFG_PD_PLL0);
1787     POWER_EnablePD(kPDRUNCFG_PD_PLL0_SSCG);
1788 
1789     /* Write PLL setup data */
1790     SYSCON->PLL0CTRL  = pSetup->pllctrl;
1791     SYSCON->PLL0NDEC  = pSetup->pllndec;
1792     SYSCON->PLL0NDEC  = pSetup->pllndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT); /* latch */
1793     SYSCON->PLL0PDEC  = pSetup->pllpdec;
1794     SYSCON->PLL0PDEC  = pSetup->pllpdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT); /* latch */
1795     SYSCON->PLL0SSCG0 = pSetup->pllsscg[0];
1796     SYSCON->PLL0SSCG1 = pSetup->pllsscg[1];
1797     SYSCON->PLL0SSCG1 =
1798         pSetup->pllsscg[1] | (1UL << SYSCON_PLL0SSCG1_MD_REQ_SHIFT) | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT); /* latch */
1799 
1800     POWER_DisablePD(kPDRUNCFG_PD_PLL0);
1801     POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
1802 
1803     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
1804     {
1805         if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL) /* normal mode */
1806         {
1807             inRate = CLOCK_GetPLL0InClockRate();
1808             prediv = findPll0PreDiv();
1809             /* Adjust input clock */
1810             clkRate = inRate / prediv;
1811 
1812             /* Need wait at least (500us + 400/Fref) (Fref in Hz result in s) to ensure the PLL is
1813                stable. The lock bit could be used to shorten the wait time when freq<20MHZ */
1814             max_pll_lock_wait_time = 500U + (400000000U / clkRate);
1815 
1816             if (clkRate < 20000000UL)
1817             {
1818                 pll_lock_wait_time = 0U;
1819                 while ((CLOCK_IsPLL0Locked() == false) && (pll_lock_wait_time < max_pll_lock_wait_time))
1820                 {
1821                     pll_lock_wait_time += 100U;
1822                     SDK_DelayAtLeastUs(100U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1823                 }
1824             }
1825             else
1826             {
1827                 SDK_DelayAtLeastUs(max_pll_lock_wait_time, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1828             }
1829         }
1830         else /* spread spectrum mode */
1831         {
1832             SDK_DelayAtLeastUs(6000U,
1833                                SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* software should use a 6 ms time interval
1834                                                                            to insure the PLL will be stable */
1835         }
1836     }
1837 
1838     /* Update current programmed PLL rate var */
1839     s_Pll0_Freq = pSetup->pllRate;
1840 
1841     return kStatus_PLL_Success;
1842 }
1843 
1844 /* Setup PLL1 Frequency from pre-calculated value */
1845 /**
1846  * brief Set PLL1 output from PLL setup structure (precise frequency)
1847  * param pSetup  : Pointer to populated PLL setup structure
1848  * return    kStatus_PLL_Success on success, or PLL setup error code
1849  * note  This function will power off the PLL, setup the PLL with the
1850  * new setup data, and then optionally powerup the PLL, wait for PLL lock,
1851  * and adjust system voltages to the new PLL rate. The function will not
1852  * alter any source clocks (ie, main systen clock) that may use the PLL,
1853  * so these should be setup prior to and after exiting the function.
1854  */
CLOCK_SetPLL1Freq(const pll_setup_t * pSetup)1855 pll_error_t CLOCK_SetPLL1Freq(const pll_setup_t *pSetup)
1856 {
1857     uint32_t inRate, clkRate, prediv;
1858     uint32_t pll_lock_wait_time     = 0U;
1859     uint32_t max_pll_lock_wait_time = 0U;
1860     /* Power off PLL during setup changes */
1861     POWER_EnablePD(kPDRUNCFG_PD_PLL1);
1862 
1863     /* Write PLL setup data */
1864     SYSCON->PLL1CTRL = pSetup->pllctrl;
1865     SYSCON->PLL1NDEC = pSetup->pllndec;
1866     SYSCON->PLL1NDEC = pSetup->pllndec | (1UL << SYSCON_PLL1NDEC_NREQ_SHIFT); /* latch */
1867     SYSCON->PLL1PDEC = pSetup->pllpdec;
1868     SYSCON->PLL1PDEC = pSetup->pllpdec | (1UL << SYSCON_PLL1PDEC_PREQ_SHIFT); /* latch */
1869     SYSCON->PLL1MDEC = pSetup->pllmdec;
1870     SYSCON->PLL1MDEC = pSetup->pllmdec | (1UL << SYSCON_PLL1MDEC_MREQ_SHIFT); /* latch */
1871 
1872     POWER_DisablePD(kPDRUNCFG_PD_PLL1);
1873 
1874     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
1875     {
1876         inRate = CLOCK_GetPLL1InClockRate();
1877         prediv = findPll1PreDiv();
1878         /* Adjust input clock */
1879         clkRate = inRate / prediv;
1880 
1881         /* Need wait at least (500us + 400/Fref) (Fref in Hz result in s) to ensure the PLL is stable.
1882            The lock bit could be used to shorten the wait time when freq<20MHZ */
1883         max_pll_lock_wait_time = 500U + (400000000U / clkRate);
1884 
1885         if (clkRate < 20000000UL)
1886         {
1887             pll_lock_wait_time = 0U;
1888             while ((CLOCK_IsPLL1Locked() == false) && (pll_lock_wait_time < max_pll_lock_wait_time))
1889             {
1890                 pll_lock_wait_time += 100U;
1891                 SDK_DelayAtLeastUs(100U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1892             }
1893         }
1894         else
1895         {
1896             SDK_DelayAtLeastUs(max_pll_lock_wait_time, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1897         }
1898     }
1899 
1900     /* Update current programmed PLL rate var */
1901     s_Pll1_Freq = pSetup->pllRate;
1902 
1903     return kStatus_PLL_Success;
1904 }
1905 
1906 /* Set PLL0 clock based on the input frequency and multiplier */
1907 /*! brief    Set PLL0 output based on the multiplier and input frequency
1908  * param multiply_by : multiplier
1909  * param input_freq  : Clock input frequency of the PLL
1910  * return    Nothing
1911  * note  Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
1912  * function does not disable or enable PLL power, wait for PLL lock,
1913  * or adjust system voltages. These must be done in the application.
1914  * The function will not alter any source clocks (ie, main systen clock)
1915  * that may use the PLL, so these should be setup prior to and after
1916  * exiting the function.
1917  */
CLOCK_SetupPLL0Mult(uint32_t multiply_by,uint32_t input_freq)1918 void CLOCK_SetupPLL0Mult(uint32_t multiply_by, uint32_t input_freq)
1919 {
1920     uint32_t cco_freq = input_freq * multiply_by;
1921     uint32_t pdec     = 1U;
1922     uint32_t selr;
1923     uint32_t seli;
1924     uint32_t selp;
1925     uint32_t mdec, ndec;
1926 
1927     while (cco_freq < 275000000U)
1928     {
1929         multiply_by <<= 1U; /* double value in each iteration */
1930         pdec <<= 1U;        /* correspondingly double pdec to cancel effect of double msel */
1931         cco_freq = input_freq * multiply_by;
1932     }
1933 
1934     selr = 0U;
1935 
1936     if (multiply_by >= 8000UL)
1937     {
1938         seli = 1UL;
1939     }
1940     else if (multiply_by >= 122UL)
1941     {
1942         seli = (uint32_t)(8000UL / multiply_by); /*floor(8000/M) */
1943     }
1944     else
1945     {
1946         seli = 2UL * ((uint32_t)(multiply_by / 4UL)) + 3UL; /* 2*floor(M/4) + 3 */
1947     }
1948 
1949     if (seli >= 63U)
1950     {
1951         seli = 63U;
1952     }
1953 
1954     {
1955         selp = 31U;
1956     }
1957 
1958     if (pdec > 1U)
1959     {
1960         pdec = pdec / 2U; /* Account for minus 1 encoding */
1961                           /* Translate P value */
1962     }
1963 
1964     mdec = (uint32_t)PLL_SSCG1_MDEC_VAL_SET(multiply_by);
1965     ndec = 0x1U; /* pre divide by 1 (hardcoded) */
1966 
1967     SYSCON->PLL0CTRL = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_BYPASSPOSTDIV(0) |
1968                        SYSCON_PLL0CTRL_BYPASSPOSTDIV2(0) | (selr << SYSCON_PLL0CTRL_SELR_SHIFT) |
1969                        (seli << SYSCON_PLL0CTRL_SELI_SHIFT) | (selp << SYSCON_PLL0CTRL_SELP_SHIFT);
1970     SYSCON->PLL0PDEC  = pdec | (1UL << SYSCON_PLL0PDEC_PREQ_SHIFT);  /* set Pdec value and assert preq */
1971     SYSCON->PLL0NDEC  = ndec | (1UL << SYSCON_PLL0NDEC_NREQ_SHIFT);  /* set Pdec value and assert preq */
1972     SYSCON->PLL0SSCG1 = mdec | (1UL << SYSCON_PLL0SSCG1_MREQ_SHIFT); /* select non sscg MDEC value, assert
1973                                                                         mreq and select mdec value */
1974 }
1975 
1976 /* Enable USB DEVICE FULL SPEED clock */
1977 /*! brief Enable USB Device FS clock.
1978  * param src : clock source
1979  * param freq: clock frequency
1980  * Enable USB Device Full Speed clock.
1981  */
CLOCK_EnableUsbfs0DeviceClock(clock_usbfs_src_t src,uint32_t freq)1982 bool CLOCK_EnableUsbfs0DeviceClock(clock_usbfs_src_t src, uint32_t freq)
1983 {
1984     bool ret = true;
1985 
1986     CLOCK_DisableClock(kCLOCK_Usbd0);
1987 
1988     if (kCLOCK_UsbfsSrcFro == src)
1989     {
1990         switch (freq)
1991         {
1992             case 96000000U:
1993                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
1994                 break;
1995 
1996             default:
1997                 ret = false;
1998                 break;
1999         }
2000         /* Turn ON FRO HF */
2001         POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
2002         /* Enable FRO 96MHz output */
2003         ANACTRL->FRO192M_CTRL =
2004             ANACTRL->FRO192M_CTRL | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK | ANACTRL_FRO192M_CTRL_USBCLKADJ_MASK;
2005         /* Select FRO 96 or 48 MHz */
2006         CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
2007     }
2008     else
2009     {
2010         /*!< Configure XTAL32M */
2011         POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);                                /* Ensure XTAL32M is powered */
2012         POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);                               /* Ensure XTAL32M is powered */
2013         (void)CLOCK_SetupExtClocking(16000000U);                              /* Enable clk_in clock */
2014         SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK;               /* Enable clk_in from XTAL32M clock  */
2015         ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system  */
2016 
2017         /*!< Set up PLL1 */
2018         POWER_DisablePD(kPDRUNCFG_PD_PLL1);
2019         CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */
2020         const pll_setup_t pll1Setup = {
2021             .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(19U) | SYSCON_PLL1CTRL_SELP(9U),
2022             .pllndec = SYSCON_PLL1NDEC_NDIV(1U),
2023             .pllpdec = SYSCON_PLL1PDEC_PDIV(5U),
2024             .pllmdec = SYSCON_PLL1MDEC_MDIV(30U),
2025             .pllRate = 48000000U,
2026             .flags   = PLL_SETUPFLAG_WAITLOCK};
2027         (void)CLOCK_SetPLL1Freq(&pll1Setup);
2028 
2029         CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
2030         CLOCK_AttachClk(kPLL1_to_USB0_CLK);
2031         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2032     }
2033     CLOCK_EnableClock(kCLOCK_Usbd0);
2034     CLOCK_EnableClock(kCLOCK_UsbRam1);
2035 
2036     return ret;
2037 }
2038 
2039 /* Enable USB HOST FULL SPEED clock */
2040 /*! brief Enable USB HOST FS clock.
2041  * param src : clock source
2042  * param freq: clock frequency
2043  * Enable USB HOST Full Speed clock.
2044  */
CLOCK_EnableUsbfs0HostClock(clock_usbfs_src_t src,uint32_t freq)2045 bool CLOCK_EnableUsbfs0HostClock(clock_usbfs_src_t src, uint32_t freq)
2046 {
2047     bool ret = true;
2048 
2049     CLOCK_DisableClock(kCLOCK_Usbhmr0);
2050     CLOCK_DisableClock(kCLOCK_Usbhsl0);
2051 
2052     if (kCLOCK_UsbfsSrcFro == src)
2053     {
2054         switch (freq)
2055         {
2056             case 96000000U:
2057                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2058                 break;
2059 
2060             default:
2061                 ret = false;
2062                 break;
2063         }
2064         /* Turn ON FRO HF */
2065         POWER_DisablePD(kPDRUNCFG_PD_FRO192M);
2066         /* Enable FRO 96MHz output */
2067         ANACTRL->FRO192M_CTRL = ANACTRL->FRO192M_CTRL | ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK;
2068         /* Select FRO 96 MHz */
2069         CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
2070     }
2071     else
2072     {
2073         /*!< Configure XTAL32M */
2074         POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);                                /* Ensure XTAL32M is powered */
2075         POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);                               /* Ensure XTAL32M is powered */
2076         (void)CLOCK_SetupExtClocking(16000000U);                              /* Enable clk_in clock */
2077         SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK;               /* Enable clk_in from XTAL32M clock  */
2078         ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system  */
2079 
2080         /*!< Set up PLL1 */
2081         POWER_DisablePD(kPDRUNCFG_PD_PLL1);
2082         CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */
2083         const pll_setup_t pll1Setup = {
2084             .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(19U) | SYSCON_PLL1CTRL_SELP(9U),
2085             .pllndec = SYSCON_PLL1NDEC_NDIV(1U),
2086             .pllpdec = SYSCON_PLL1PDEC_PDIV(5U),
2087             .pllmdec = SYSCON_PLL1MDEC_MDIV(30U),
2088             .pllRate = 48000000U,
2089             .flags   = PLL_SETUPFLAG_WAITLOCK};
2090         (void)CLOCK_SetPLL1Freq(&pll1Setup);
2091 
2092         CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
2093         CLOCK_AttachClk(kPLL1_to_USB0_CLK);
2094         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2095     }
2096     CLOCK_EnableClock(kCLOCK_Usbhmr0);
2097     CLOCK_EnableClock(kCLOCK_Usbhsl0);
2098     CLOCK_EnableClock(kCLOCK_UsbRam1);
2099 
2100     return ret;
2101 }
2102 
2103 /* Enable USB PHY clock */
CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src,uint32_t freq)2104 bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
2105 {
2106     volatile uint32_t i;
2107     uint32_t phyPllDiv  = 0U;
2108     uint16_t multiplier = 0U;
2109     bool ret            = true;
2110 
2111     POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
2112     POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
2113     POWER_DisablePD(kPDRUNCFG_PD_FRO32K);   /*!< Ensure FRO32k is on  */
2114     POWER_DisablePD(kPDRUNCFG_PD_XTAL32K);  /*!< Ensure xtal32k is on  */
2115     POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /*!< Ensure xtal32k is on  */
2116     POWER_DisablePD(kPDRUNCFG_PD_LDOUSBHS); /*!< Ensure xtal32k is on  */
2117 
2118     SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_ANALOG_CTRL(1);
2119     SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_PHY(1);
2120 
2121     /* wait to make sure PHY power is fully up */
2122     i = 100000U;
2123     while ((i--) != 0U)
2124     {
2125         __ASM("nop");
2126     }
2127 
2128     USBPHY->CTRL_CLR = USBPHY_CTRL_SFTRST_MASK;
2129 
2130     multiplier = (uint16_t)(480000000UL / freq);
2131 
2132     switch (multiplier)
2133     {
2134         case 15U:
2135         {
2136             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(0U);
2137             break;
2138         }
2139         case 16U:
2140         {
2141             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(1U);
2142             break;
2143         }
2144         case 20U:
2145         {
2146             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(2U);
2147             break;
2148         }
2149         case 24U:
2150         {
2151             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(4U);
2152             break;
2153         }
2154         case 25U:
2155         {
2156             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(5U);
2157             break;
2158         }
2159         case 30U:
2160         {
2161             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(6U);
2162             break;
2163         }
2164         default:
2165         {
2166             ret = false;
2167             break;
2168         }
2169     }
2170 
2171     if (ret)
2172     {
2173         USBPHY->PLL_SIC     = (USBPHY->PLL_SIC & ~USBPHY_PLL_SIC_PLL_DIV_SEL(0x7)) | phyPllDiv;
2174         USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_REG_ENABLE_MASK;
2175         USBPHY->PLL_SIC_CLR = (1UL << 16U); // Reserved. User must set this bit to 0x0
2176         USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_POWER_MASK;
2177         USBPHY->PLL_SIC_SET = USBPHY_PLL_SIC_SET_PLL_EN_USB_CLKS_MASK;
2178 
2179         USBPHY->CTRL_CLR = USBPHY_CTRL_CLR_CLKGATE_MASK;
2180         USBPHY->PWD_SET  = 0x0;
2181     }
2182 
2183     return ret;
2184 }
2185 
2186 /* Enable USB DEVICE HIGH SPEED clock */
CLOCK_EnableUsbhs0DeviceClock(clock_usbhs_src_t src,uint32_t freq)2187 bool CLOCK_EnableUsbhs0DeviceClock(clock_usbhs_src_t src, uint32_t freq)
2188 {
2189     SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_RAM(1);
2190     SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_DEV(1);
2191 
2192     /* 16 MHz will be driven by the tb on the xtal1 pin of XTAL32M */
2193     SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clock_in clock for clock module. */
2194     ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT(1);
2195     return true;
2196 }
2197 
2198 /* Enable USB HOST HIGH SPEED clock */
CLOCK_EnableUsbhs0HostClock(clock_usbhs_src_t src,uint32_t freq)2199 bool CLOCK_EnableUsbhs0HostClock(clock_usbhs_src_t src, uint32_t freq)
2200 {
2201     SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_RAM(1);
2202     SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_USB1_HOST(1);
2203 
2204     /* 16 MHz will be driven by the tb on the xtal1 pin of XTAL32M */
2205     SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clock_in clock for clock module. */
2206     ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_PLL_USB_OUT(1);
2207 
2208     return true;
2209 }
2210 
2211 /*! @brief Enable the OSTIMER 32k clock.
2212  *  @return  Nothing
2213  */
CLOCK_EnableOstimer32kClock(void)2214 void CLOCK_EnableOstimer32kClock(void)
2215 {
2216     PMC->OSTIMERr |= PMC_OSTIMER_CLOCKENABLE_MASK;
2217 }
2218