1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016 - 2019 , NXP
4  * All rights reserved.
5  *
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  */
9 
10 #include "fsl_clock.h"
11 #include "fsl_power.h"
12 /*******************************************************************************
13  * Definitions
14  ******************************************************************************/
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.clock"
18 #endif
19 #define NVALMAX (0x100U)
20 #define PVALMAX (0x20U)
21 #define MVALMAX (0x8000U)
22 
23 #define USB_NVALMAX (0x4U)
24 #define USB_PVALMAX (0x8U)
25 #define USB_MVALMAX (0x100U)
26 
27 #define PLL_MAX_N_DIV 0x100U
28 #define USB_PLL_MAX_N_DIV 0x100U
29 
30 #define PLL_MDEC_VAL_P (0U)                          /*!<  MDEC is in bits  16 downto 0 */
31 #define PLL_MDEC_VAL_M (0x1FFFFUL << PLL_MDEC_VAL_P) /*!<  NDEC is in bits  9 downto 0 */
32 #define PLL_NDEC_VAL_P (0U)                          /*!<  NDEC is in bits  9:0 */
33 #define PLL_NDEC_VAL_M (0x3FFUL << PLL_NDEC_VAL_P)
34 #define PLL_PDEC_VAL_P (0U) /*!<  PDEC is in bits 6:0 */
35 #define PLL_PDEC_VAL_M (0x7FUL << PLL_PDEC_VAL_P)
36 
37 #define PLL_MIN_CCO_FREQ_MHZ (275000000U)
38 #define PLL_MAX_CCO_FREQ_MHZ (550000000U)
39 #define PLL_LOWER_IN_LIMIT (4000U) /*!<  Minimum PLL input rate */
40 #define PLL_MIN_IN_SSMODE (2000000U)
41 #define PLL_MAX_IN_SSMODE (4000000U)
42 
43 /*!<  Middle of the range values for spread-spectrum */
44 #define PLL_SSCG_MF_FREQ_VALUE 4U
45 #define PLL_SSCG_MC_COMP_VALUE 2U
46 #define PLL_SSCG_MR_DEPTH_VALUE 4U
47 #define PLL_SSCG_DITHER_VALUE 0U
48 
49 /*!<  USB PLL CCO MAX AND MIN FREQ */
50 #define USB_PLL_MIN_CCO_FREQ_MHZ (156000000U)
51 #define USB_PLL_MAX_CCO_FREQ_MHZ (320000000U)
52 #define USB_PLL_LOWER_IN_LIMIT (1000000U) /*!<  Minimum PLL input rate */
53 
54 #define USB_PLL_MSEL_VAL_P (0U) /*!<  MSEL is in bits  7 downto 0 */
55 #define USB_PLL_MSEL_VAL_M (0xFFU)
56 #define USB_PLL_PSEL_VAL_P (8U) /*!<  PDEC is in bits 9:8 */
57 #define USB_PLL_PSEL_VAL_M (0x3U)
58 #define USB_PLL_NSEL_VAL_P (10U) /*!<  NDEC is in bits  11:10 */
59 #define USB_PLL_NSEL_VAL_M (0x3U)
60 
61 /*!<  SYS PLL NDEC reg */
62 #define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
63 /*!<  SYS PLL PDEC reg */
64 #define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
65 /*!<  SYS PLL MDEC reg */
66 #define PLL_MDEC_VAL_SET(value) (((unsigned long)(value) << PLL_MDEC_VAL_P) & PLL_MDEC_VAL_M)
67 
68 /*!<  SYS PLL NSEL reg */
69 #define USB_PLL_NSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_NSEL_VAL_M) << USB_PLL_NSEL_VAL_P)
70 /*!<  SYS PLL PSEL reg */
71 #define USB_PLL_PSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_PSEL_VAL_M) << USB_PLL_PSEL_VAL_P)
72 /*!<  SYS PLL MSEL reg */
73 #define USB_PLL_MSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_MSEL_VAL_M) << USB_PLL_MSEL_VAL_P)
74 
75 /*!<  FRAC control */
76 #define AUDIO_PLL_FRACT_MD_P (0U)
77 #define AUDIO_PLL_FRACT_MD_INT_P (15U)
78 #define AUDIO_PLL_FRACT_MD_M (0x7FFFUL << AUDIO_PLL_FRACT_MD_P)
79 #define AUDIO_PLL_FRACT_MD_INT_M (0x7FUL << AUDIO_PLL_FRACT_MD_INT_P)
80 
81 #define AUDIO_PLL_MD_FRACT_SET(value) (((unsigned long)(value) << AUDIO_PLL_FRACT_MD_P) & PLL_FRAC_MD_FRACT_M)
82 #define AUDIO_PLL_MD_INT_SET(value) (((unsigned long)(value) << AUDIO_PLL_FRACT_MD_INT_P) & AUDIO_PLL_FRACT_MD_INT_M)
83 
84 /* Saved value of PLL output rate, computed whenever needed to save run-time
85    computation on each call to retrive the PLL rate. */
86 static uint32_t s_Pll_Freq;
87 static uint32_t s_Usb_Pll_Freq;
88 static uint32_t s_Audio_Pll_Freq;
89 
90 /** External clock rate on the CLKIN pin in Hz. If not used,
91     set this to 0. Otherwise, set it to the exact rate in Hz this pin is
92     being driven at. */
93 static const uint32_t s_I2S_Mclk_Freq   = 0U;
94 static const uint32_t s_Ext_Clk_Freq    = 12000000U;
95 static const uint32_t s_Lcd_Clk_In_Freq = 0U;
96 
97 /*******************************************************************************
98  * Variables
99  ******************************************************************************/
100 
101 /*******************************************************************************
102  * Prototypes
103  ******************************************************************************/
104 /* Find encoded NDEC value for raw N value, max N = NVALMAX */
105 static uint32_t pllEncodeN(uint32_t N);
106 /* Find decoded N value for raw NDEC value */
107 static uint32_t pllDecodeN(uint32_t NDEC);
108 /* Find encoded PDEC value for raw P value, max P = PVALMAX */
109 static uint32_t pllEncodeP(uint32_t P);
110 /* Find decoded P value for raw PDEC value */
111 static uint32_t pllDecodeP(uint32_t PDEC);
112 /* Find encoded MDEC value for raw M value, max M = MVALMAX */
113 static uint32_t pllEncodeM(uint32_t M);
114 /* Find decoded M value for raw MDEC value */
115 static uint32_t pllDecodeM(uint32_t MDEC);
116 /* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
117 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR);
118 /* Get predivider (N) from PLL NDEC setting */
119 static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg);
120 /* Get postdivider (P) from PLL PDEC setting */
121 static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg);
122 /* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
123 static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg);
124 /* Convert the binary to fractional part */
125 static double Binary2Fractional(uint32_t binaryPart);
126 /* Get the greatest common divisor */
127 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n);
128 /* Set PLL output based on desired output rate */
129 static pll_error_t CLOCK_GetPllConfig(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup);
130 
131 /* Update local PLL rate variable */
132 static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup);
133 static void CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t *pSetup);
134 
135 static const uint8_t wdtFreqLookup[32] = {0,  8,  12, 15, 18, 20, 24, 26, 28, 30, 32, 34, 36, 38, 40, 41,
136                                           42, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 59, 60, 61};
137 /*******************************************************************************
138  * Code
139  ******************************************************************************/
140 
141 /* Clock Selection for IP */
142 /**
143  * brief	Configure the clock selection muxes.
144  * param	connection	: Clock to be configured.
145  * return	Nothing
146  */
CLOCK_AttachClk(clock_attach_id_t connection)147 void CLOCK_AttachClk(clock_attach_id_t connection)
148 {
149     uint8_t mux;
150     uint8_t sel;
151     uint16_t item;
152     uint32_t tmp32 = (uint32_t)connection;
153     uint32_t i;
154     volatile uint32_t *pClkSel;
155 
156     pClkSel = &(SYSCON->MAINCLKSELA);
157 
158     if (kNONE_to_NONE != connection)
159     {
160         for (i = 0U; i < 2U; i++)
161         {
162             if (tmp32 == 0U)
163             {
164                 break;
165             }
166             item = (uint16_t)GET_ID_ITEM(tmp32);
167             if (0U != item)
168             {
169                 mux = GET_ID_ITEM_MUX(item);
170                 sel = GET_ID_ITEM_SEL(item);
171                 if (mux == CM_ASYNCAPB)
172                 {
173                     SYSCON->ASYNCAPBCTRL          = SYSCON_ASYNCAPBCTRL_ENABLE(1);
174                     ASYNC_SYSCON->ASYNCAPBCLKSELA = sel;
175                 }
176                 else
177                 {
178                     ((volatile uint32_t *)pClkSel)[mux] = sel;
179                 }
180             }
181             tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!<  pick up next descriptor */
182         }
183     }
184 }
185 
186 /* Return the actual clock attach id */
187 /**
188  * brief   Get the actual clock attach id.
189  * This fuction uses the offset in input attach id, then it reads the actual source value in
190  * the register and combine the offset to obtain an actual attach id.
191  * param   attachId  : Clock attach id to get.
192  * return  Clock source value.
193  */
CLOCK_GetClockAttachId(clock_attach_id_t attachId)194 clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId)
195 {
196     uint8_t mux;
197     uint32_t actualSel;
198     uint32_t tmp32 = (uint32_t)attachId;
199     uint32_t i;
200     uint32_t actualAttachId = 0U;
201     uint32_t selector       = GET_ID_SELECTOR(tmp32);
202     volatile uint32_t *pClkSel;
203 
204     pClkSel = &(SYSCON->MAINCLKSELA);
205 
206     if (kNONE_to_NONE == attachId)
207     {
208         return kNONE_to_NONE;
209     }
210 
211     for (i = 0U; i < 2U; i++)
212     {
213         mux = GET_ID_ITEM_MUX(tmp32);
214         if (0U != tmp32)
215         {
216             if (mux == CM_ASYNCAPB)
217             {
218                 actualSel = ASYNC_SYSCON->ASYNCAPBCLKSELA;
219             }
220             else
221             {
222                 actualSel = ((volatile uint32_t *)pClkSel)[mux];
223             }
224 
225             /* Consider the combination of two registers */
226             actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i);
227         }
228         tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!<  pick up next descriptor */
229     }
230 
231     actualAttachId |= selector;
232 
233     return (clock_attach_id_t)actualAttachId;
234 }
235 
236 /* Set IP Clock Divider */
237 /**
238  * brief	Setup peripheral clock dividers.
239  * param	div_name	: Clock divider name
240  * param divided_by_value: Value to be divided
241  * param reset :  Whether to reset the divider counter.
242  * return	Nothing
243  */
CLOCK_SetClkDiv(clock_div_name_t div_name,uint32_t divided_by_value,bool reset)244 void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
245 {
246     volatile uint32_t *pClkDiv;
247 
248     pClkDiv = &(SYSCON->SYSTICKCLKDIV);
249     if (reset)
250     {
251         ((volatile uint32_t *)pClkDiv)[(uint32_t)div_name] = 1UL << 29U;
252     }
253     if (divided_by_value == 0U) /*!<  halt */
254     {
255         ((volatile uint32_t *)pClkDiv)[(uint32_t)div_name] = 1UL << 30U;
256     }
257     else
258     {
259         ((volatile uint32_t *)pClkDiv)[(uint32_t)div_name] = (divided_by_value - 1U);
260     }
261 }
262 
263 /* Set FRO Clocking */
264 /**
265  * brief	Initialize the Core clock to given frequency (12, 48 or 96 MHz).
266  * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is
267  * enabled.
268  * param	iFreq	: Desired frequency (must be one of #CLK_FRO_12MHZ or #CLK_FRO_48MHZ or #CLK_FRO_96MHZ)
269  * return	returns success or fail status.
270  */
CLOCK_SetupFROClocking(uint32_t iFreq)271 status_t CLOCK_SetupFROClocking(uint32_t iFreq)
272 {
273     uint32_t usb_adj;
274     if ((iFreq != 12000000U) && (iFreq != 48000000U) && (iFreq != 96000000U))
275     {
276         return kStatus_Fail;
277     }
278     /* Power up the FRO and set this as the base clock */
279     POWER_DisablePD(kPDRUNCFG_PD_FRO_EN);
280     /* back up the value of whether USB adj is selected, in which case we will have a value of 1 else 0 */
281     usb_adj = ((SYSCON->FROCTRL) & SYSCON_FROCTRL_USBCLKADJ_MASK) >> SYSCON_FROCTRL_USBCLKADJ_SHIFT;
282 
283     if (iFreq > 12000000U)
284     {
285         /* Call ROM API to set FRO */
286         set_fro_frequency(iFreq);
287         if (iFreq == 96000000U)
288         {
289             SYSCON->FROCTRL |= (SYSCON_FROCTRL_SEL(1) | SYSCON_FROCTRL_WRTRIM(1) | SYSCON_FROCTRL_USBCLKADJ(usb_adj) |
290                                 SYSCON_FROCTRL_HSPDCLK(1));
291         }
292         else
293         {
294             SYSCON->FROCTRL |= (SYSCON_FROCTRL_SEL(0) | SYSCON_FROCTRL_WRTRIM(1) | SYSCON_FROCTRL_USBCLKADJ(usb_adj) |
295                                 SYSCON_FROCTRL_HSPDCLK(1));
296         }
297     }
298     else
299     {
300         SYSCON->FROCTRL &= ~SYSCON_FROCTRL_HSPDCLK(1);
301     }
302 
303     return kStatus_Success;
304 }
305 
306 /* Get CLOCK OUT Clk */
307 /*! brief	Return Frequency of ClockOut
308  *  return	Frequency of ClockOut
309  */
CLOCK_GetClockOutClkFreq(void)310 uint32_t CLOCK_GetClockOutClkFreq(void)
311 {
312     uint32_t freq = 0U;
313 
314     switch (SYSCON->CLKOUTSELA)
315     {
316         case 0U:
317             freq = CLOCK_GetCoreSysClkFreq();
318             break;
319 
320         case 1U:
321             freq = CLOCK_GetExtClkFreq();
322             break;
323 
324         case 2U:
325             freq = CLOCK_GetWdtOscFreq();
326             break;
327 
328         case 3U:
329             freq = CLOCK_GetFroHfFreq();
330             break;
331 
332         case 4U:
333             freq = CLOCK_GetPllOutFreq();
334             break;
335 
336         case 5U:
337             freq = CLOCK_GetUsbPllOutFreq();
338             break;
339 
340         case 6U:
341             freq = CLOCK_GetAudioPllOutFreq();
342             break;
343 
344         case 7U:
345             freq = CLOCK_GetOsc32KFreq();
346             break;
347 
348         default:
349             freq = 0U;
350             break;
351     }
352     return freq / ((SYSCON->CLKOUTDIV & 0xffU) + 1U);
353 }
354 
355 /* Get SPIFI Clk */
356 /*! brief	Return Frequency of Spifi Clock
357  *  return	Frequency of Spifi.
358  */
CLOCK_GetSpifiClkFreq(void)359 uint32_t CLOCK_GetSpifiClkFreq(void)
360 {
361     uint32_t freq = 0U;
362 
363     switch (SYSCON->SPIFICLKSEL)
364     {
365         case 0U:
366             freq = CLOCK_GetCoreSysClkFreq();
367             break;
368         case 1U:
369             freq = CLOCK_GetPllOutFreq();
370             break;
371         case 2U:
372             freq = CLOCK_GetUsbPllOutFreq();
373             break;
374         case 3U:
375             freq = CLOCK_GetFroHfFreq();
376             break;
377         case 4U:
378             freq = CLOCK_GetAudioPllOutFreq();
379             break;
380         case 7U:
381             freq = 0U;
382             break;
383         default:
384             freq = 0U;
385             break;
386     }
387 
388     return freq / ((SYSCON->SPIFICLKDIV & 0xffU) + 1U);
389 }
390 
391 /* Get ADC Clk */
392 /*! brief	Return Frequency of Adc Clock
393  *  return	Frequency of Adc Clock.
394  */
CLOCK_GetAdcClkFreq(void)395 uint32_t CLOCK_GetAdcClkFreq(void)
396 {
397     uint32_t freq = 0U;
398 
399     switch (SYSCON->ADCCLKSEL)
400     {
401         case 0U:
402             freq = CLOCK_GetFroHfFreq();
403             break;
404         case 1U:
405             freq = CLOCK_GetPllOutFreq();
406             break;
407         case 2U:
408             freq = CLOCK_GetUsbPllOutFreq();
409             break;
410         case 3U:
411             freq = CLOCK_GetAudioPllOutFreq();
412             break;
413         case 7U:
414             freq = 0U;
415             break;
416         default:
417             freq = 0U;
418             break;
419     }
420 
421     return freq / ((SYSCON->ADCCLKDIV & 0xffU) + 1U);
422 }
423 
424 /* Get USB0 Clk */
425 /*! brief	Return Frequency of Usb0 Clock
426  *  return	Frequency of Usb0 Clock.
427  */
CLOCK_GetUsb0ClkFreq(void)428 uint32_t CLOCK_GetUsb0ClkFreq(void)
429 {
430     uint32_t freq = 0U;
431 
432     switch (SYSCON->USB0CLKSEL)
433     {
434         case 0U:
435             freq = CLOCK_GetFroHfFreq();
436             break;
437         case 1U:
438             freq = CLOCK_GetPllOutFreq();
439             break;
440         case 2U:
441             freq = CLOCK_GetUsbPllOutFreq();
442             break;
443         case 7U:
444             freq = 0U;
445             break;
446 
447         default:
448             freq = 0U;
449             break;
450     }
451 
452     return freq / ((SYSCON->USB0CLKDIV & 0xffU) + 1U);
453 }
454 
455 /* Get USB1 Clk */
456 /*! brief	Return Frequency of Usb1 Clock
457  *  return	Frequency of Usb1 Clock.
458  */
CLOCK_GetUsb1ClkFreq(void)459 uint32_t CLOCK_GetUsb1ClkFreq(void)
460 {
461     uint32_t freq = 0U;
462 
463     switch (SYSCON->USB1CLKSEL)
464     {
465         case 0U:
466             freq = CLOCK_GetCoreSysClkFreq();
467             break;
468         case 1U:
469             freq = CLOCK_GetPllOutFreq();
470             break;
471         case 2U:
472             freq = CLOCK_GetUsbPllOutFreq();
473             break;
474         case 7U:
475             freq = 0U;
476             break;
477 
478         default:
479             freq = 0U;
480             break;
481     }
482 
483     return freq / ((SYSCON->USB1CLKDIV & 0xffU) + 1U);
484 }
485 
486 /* Get MCLK Clk */
487 /*! brief	Return Frequency of MClk Clock
488  *  return	Frequency of MClk Clock.
489  */
CLOCK_GetMclkClkFreq(void)490 uint32_t CLOCK_GetMclkClkFreq(void)
491 {
492     uint32_t freq = 0U;
493 
494     switch (SYSCON->MCLKCLKSEL)
495     {
496         case 0U:
497             freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFCLKDIV & 0xffu) + 1U);
498             break;
499         case 1U:
500             freq = CLOCK_GetAudioPllOutFreq();
501             break;
502         case 7U:
503             freq = 0U;
504             break;
505 
506         default:
507             freq = 0U;
508             break;
509     }
510 
511     return freq / ((SYSCON->MCLKDIV & 0xffU) + 1U);
512 }
513 
514 /* Get SCTIMER Clk */
515 /*! brief	Return Frequency of SCTimer Clock
516  *  return	Frequency of SCTimer Clock.
517  */
CLOCK_GetSctClkFreq(void)518 uint32_t CLOCK_GetSctClkFreq(void)
519 {
520     uint32_t freq = 0U;
521 
522     switch (SYSCON->SCTCLKSEL)
523     {
524         case 0U:
525             freq = CLOCK_GetCoreSysClkFreq();
526             break;
527         case 1U:
528             freq = CLOCK_GetPllOutFreq();
529             break;
530         case 2U:
531             freq = CLOCK_GetFroHfFreq();
532             break;
533         case 3U:
534             freq = CLOCK_GetAudioPllOutFreq();
535             break;
536         case 7U:
537             freq = 0U;
538             break;
539 
540         default:
541             freq = 0U;
542             break;
543     }
544 
545     return freq / ((SYSCON->SCTCLKDIV & 0xffU) + 1U);
546 }
547 
548 /* Get SDIO Clk */
549 /*! brief	Return Frequency of SDIO Clock
550  *  return	Frequency of SDIO Clock.
551  */
CLOCK_GetSdioClkFreq(void)552 uint32_t CLOCK_GetSdioClkFreq(void)
553 {
554     uint32_t freq = 0U;
555 
556     switch (SYSCON->SDIOCLKSEL)
557     {
558         case 0U:
559             freq = CLOCK_GetCoreSysClkFreq();
560             break;
561         case 1U:
562             freq = CLOCK_GetPllOutFreq();
563             break;
564         case 2U:
565             freq = CLOCK_GetUsbPllOutFreq();
566             break;
567         case 3U:
568             freq = CLOCK_GetFroHfFreq();
569             break;
570         case 4U:
571             freq = CLOCK_GetAudioPllOutFreq();
572             break;
573         case 7U:
574             freq = 0U;
575             break;
576         default:
577             freq = 0U;
578             break;
579     }
580 
581     return freq / ((SYSCON->SDIOCLKDIV & 0xffU) + 1U);
582 }
583 
584 /* Get LCD Clk */
585 /*! brief	Return Frequency of LCD Clock
586  *  return	Frequency of LCD Clock.
587  */
CLOCK_GetLcdClkFreq(void)588 uint32_t CLOCK_GetLcdClkFreq(void)
589 {
590     uint32_t freq = 0U;
591 
592     switch (SYSCON->LCDCLKSEL)
593     {
594         case 0U:
595             freq = CLOCK_GetCoreSysClkFreq();
596             break;
597         case 1U:
598             freq = CLOCK_GetLcdClkIn();
599             break;
600         case 2U:
601             freq = CLOCK_GetFroHfFreq();
602             break;
603         case 3U:
604             freq = 0U;
605             break;
606 
607         default:
608             freq = 0U;
609             break;
610     }
611 
612     return freq / ((SYSCON->LCDCLKDIV & 0xffU) + 1U);
613 }
614 
615 /* Get LCD CLK IN Clk */
616 /*! brief	Return Frequency of LCD CLKIN Clock
617  *  return	Frequency of LCD CLKIN Clock.
618  */
CLOCK_GetLcdClkIn(void)619 uint32_t CLOCK_GetLcdClkIn(void)
620 {
621     return s_Lcd_Clk_In_Freq;
622 }
623 
624 /* Get FRO 12M Clk */
625 /*! brief	Return Frequency of FRO 12MHz
626  *  return	Frequency of FRO 12MHz
627  */
CLOCK_GetFro12MFreq(void)628 uint32_t CLOCK_GetFro12MFreq(void)
629 {
630     return (0U != (SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK)) ? 0U : 12000000U;
631 }
632 
633 /* Get EXT OSC Clk */
634 /*! brief	Return Frequency of External Clock
635  *  return	Frequency of External Clock. If no external clock is used returns 0.
636  */
CLOCK_GetExtClkFreq(void)637 uint32_t CLOCK_GetExtClkFreq(void)
638 {
639     return s_Ext_Clk_Freq;
640 }
641 
642 /* Get WATCH DOG Clk */
643 /*! brief	Return Frequency of Watchdog Oscillator
644  *  return	Frequency of Watchdog Oscillator
645  */
CLOCK_GetWdtOscFreq(void)646 uint32_t CLOCK_GetWdtOscFreq(void)
647 {
648     uint8_t freq_sel, div_sel;
649     if (0U != (SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK))
650     {
651         return 0U;
652     }
653     else
654     {
655         div_sel = (uint8_t)(((SYSCON->WDTOSCCTRL & 0x1fU) + 1U) << 1U);
656         freq_sel =
657             wdtFreqLookup[((SYSCON->WDTOSCCTRL & SYSCON_WDTOSCCTRL_FREQSEL_MASK) >> SYSCON_WDTOSCCTRL_FREQSEL_SHIFT)];
658         return ((uint32_t)freq_sel * 50000U) / ((uint32_t)div_sel);
659     }
660 }
661 
662 /* Get HF FRO Clk */
663 /*! brief	Return Frequency of High-Freq output of FRO
664  *  return	Frequency of High-Freq output of FRO
665  */
CLOCK_GetFroHfFreq(void)666 uint32_t CLOCK_GetFroHfFreq(void)
667 {
668     uint32_t freq;
669 
670     if ((0U != (SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK)) ||
671         (0U == (SYSCON->FROCTRL & SYSCON_FROCTRL_HSPDCLK_MASK)))
672     {
673         freq = 0U;
674     }
675     else
676     {
677         if (0U != (SYSCON->FROCTRL & SYSCON_FROCTRL_SEL_MASK))
678         {
679             freq = 96000000U;
680         }
681         else
682         {
683             freq = 48000000U;
684         }
685     }
686 
687     return freq;
688 }
689 
690 /* Get SYSTEM PLL Clk */
691 /*! brief	Return Frequency of PLL
692  *  return	Frequency of PLL
693  */
CLOCK_GetPllOutFreq(void)694 uint32_t CLOCK_GetPllOutFreq(void)
695 {
696     return s_Pll_Freq;
697 }
698 
699 /* Get AUDIO PLL Clk */
700 /*! brief	Return Frequency of AUDIO PLL
701  *  return	Frequency of PLL
702  */
CLOCK_GetAudioPllOutFreq(void)703 uint32_t CLOCK_GetAudioPllOutFreq(void)
704 {
705     return s_Audio_Pll_Freq;
706 }
707 
708 /* Get USB PLL Clk */
709 /*! brief	Return Frequency of USB PLL
710  *  return	Frequency of PLL
711  */
CLOCK_GetUsbPllOutFreq(void)712 uint32_t CLOCK_GetUsbPllOutFreq(void)
713 {
714     return s_Usb_Pll_Freq;
715 }
716 
717 /* Get RTC OSC Clk */
718 /*! brief	Return Frequency of 32kHz osc
719  *  return	Frequency of 32kHz osc
720  */
CLOCK_GetOsc32KFreq(void)721 uint32_t CLOCK_GetOsc32KFreq(void)
722 {
723     return CLK_RTC_32K_CLK; /* Needs to be corrected to check that RTC Clock is enabled */
724 }
725 
726 /* Get MAIN Clk */
727 /*! brief	Return Frequency of Core System
728  *  return	Frequency of Core System
729  */
CLOCK_GetCoreSysClkFreq(void)730 uint32_t CLOCK_GetCoreSysClkFreq(void)
731 {
732     uint32_t freq = 0U;
733 
734     switch (SYSCON->MAINCLKSELB)
735     {
736         case 0U:
737             if (SYSCON->MAINCLKSELA == 0U)
738             {
739                 freq = CLOCK_GetFro12MFreq();
740             }
741             else if (SYSCON->MAINCLKSELA == 1U)
742             {
743                 freq = CLOCK_GetExtClkFreq();
744             }
745             else if (SYSCON->MAINCLKSELA == 2U)
746             {
747                 freq = CLOCK_GetWdtOscFreq();
748             }
749             else if (SYSCON->MAINCLKSELA == 3U)
750             {
751                 freq = CLOCK_GetFroHfFreq();
752             }
753             else
754             {
755                 /* For MISRA C-2012 Rule 15.7 */
756             }
757             break;
758         case 2U:
759             freq = CLOCK_GetPllOutFreq();
760             break;
761 
762         case 3U:
763             freq = CLOCK_GetOsc32KFreq();
764             break;
765 
766         default:
767             freq = 0U;
768             break;
769     }
770 
771     return freq;
772 }
773 
774 /* Get I2S MCLK Clk */
775 /*! brief	Return Frequency of I2S MCLK Clock
776  *  return	Frequency of I2S MCLK Clock
777  */
CLOCK_GetI2SMClkFreq(void)778 uint32_t CLOCK_GetI2SMClkFreq(void)
779 {
780     return s_I2S_Mclk_Freq;
781 }
782 
783 /* Get ASYNC APB Clk */
784 /*! brief	Return Frequency of Asynchronous APB Clock
785  *  return	Frequency of Asynchronous APB Clock Clock
786  */
CLOCK_GetAsyncApbClkFreq(void)787 uint32_t CLOCK_GetAsyncApbClkFreq(void)
788 {
789     async_clock_src_t clkSrc;
790     uint32_t clkRate;
791 
792     clkSrc = CLOCK_GetAsyncApbClkSrc();
793 
794     switch (clkSrc)
795     {
796         case kCLOCK_AsyncMainClk:
797             clkRate = CLOCK_GetCoreSysClkFreq();
798             break;
799         case kCLOCK_AsyncFro12Mhz:
800             clkRate = CLK_FRO_12MHZ;
801             break;
802         default:
803             clkRate = 0U;
804             break;
805     }
806 
807     return clkRate;
808 }
809 
810 /* Get MCAN Clk */
811 /*! brief	Return Frequency of MCAN Clock
812  *  param	MCanSel : 0U: MCAN0; 1U: MCAN1
813  *  return	Frequency of MCAN Clock
814  */
CLOCK_GetMCanClkFreq(uint32_t MCanSel)815 uint32_t CLOCK_GetMCanClkFreq(uint32_t MCanSel)
816 {
817     uint32_t freq = 0U;
818     switch (MCanSel)
819     {
820         case 0U:
821             freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->CAN0CLKDIV & 0xffU) + 1U);
822             break;
823         case 1U:
824             freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->CAN1CLKDIV & 0xffU) + 1U);
825             break;
826 
827         default:
828             freq = 0U;
829             break;
830     }
831 
832     return freq;
833 }
834 
835 /* Get FLEXCOMM Clk */
836 /*! brief	Return Frequency of Flexcomm functional Clock
837  *  return	Frequency of Flexcomm functional Clock
838  */
CLOCK_GetFlexCommClkFreq(uint32_t id)839 uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
840 {
841     uint32_t freq = 0U;
842 
843     switch (SYSCON->FCLKSEL[id])
844     {
845         case 0U:
846             freq = CLOCK_GetFro12MFreq();
847             break;
848         case 1U:
849             freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFCLKDIV & SYSCON_FROHFCLKDIV_DIV_MASK) + 1U);
850             break;
851         case 2U:
852             freq = CLOCK_GetPllOutFreq();
853             break;
854         case 3U:
855             freq = CLOCK_GetI2SMClkFreq();
856             break;
857         case 4U:
858             freq = CLOCK_GetFrgClkFreq();
859             break;
860 
861         default:
862             freq = 0U;
863             break;
864     }
865 
866     return freq;
867 }
868 
869 /* Get FRG Clk */
870 /*! brief	Return Frequency of FRG input clock
871  *  return	Frequency value
872  */
CLOCK_GetFRGInputClock(void)873 uint32_t CLOCK_GetFRGInputClock(void)
874 {
875     uint32_t freq = 0U;
876 
877     switch (SYSCON->FRGCLKSEL)
878     {
879         case 0U:
880             freq = CLOCK_GetCoreSysClkFreq();
881             break;
882         case 1U:
883             freq = CLOCK_GetPllOutFreq();
884             break;
885         case 2U:
886             freq = CLOCK_GetFro12MFreq();
887             break;
888         case 3U:
889             freq = CLOCK_GetFroHfFreq();
890             break;
891 
892         default:
893             freq = 0U;
894             break;
895     }
896 
897     return freq;
898 }
899 
900 /* Get FRG Clk */
901 /*! brief  Return Frequency of frg
902  *  return Frequency of FRG
903  */
CLOCK_GetFrgClkFreq(void)904 uint32_t CLOCK_GetFrgClkFreq(void)
905 {
906     uint32_t freq = 0U;
907 
908     if ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_DIV_MASK) == SYSCON_FRGCTRL_DIV_MASK)
909     {
910         freq = (uint32_t)(((uint64_t)CLOCK_GetFRGInputClock() * (SYSCON_FRGCTRL_DIV_MASK + 1U)) /
911                           ((SYSCON_FRGCTRL_DIV_MASK + 1U) +
912                            ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_MULT_MASK) >> SYSCON_FRGCTRL_MULT_SHIFT)));
913     }
914     else
915     {
916         freq = 0U;
917     }
918 
919     return freq;
920 }
921 
922 /* Get DMIC Clk */
923 /*! brief  Return Frequency of dmic
924  *  return Frequency of DMIC
925  */
CLOCK_GetDmicClkFreq(void)926 uint32_t CLOCK_GetDmicClkFreq(void)
927 {
928     uint32_t freq = 0U;
929 
930     switch (SYSCON->DMICCLKSEL)
931     {
932         case 0U:
933             freq = CLOCK_GetFro12MFreq();
934             break;
935         case 1U:
936             freq = CLOCK_GetFroHfFreq();
937             break;
938         case 2U:
939             freq = CLOCK_GetPllOutFreq();
940             break;
941         case 3U:
942             freq = CLOCK_GetI2SMClkFreq();
943             break;
944         case 4U:
945             freq = CLOCK_GetCoreSysClkFreq();
946             break;
947         case 5U:
948             freq = CLOCK_GetWdtOscFreq();
949             break;
950         default:
951             freq = 0U;
952             break;
953     }
954 
955     return freq / ((SYSCON->DMICCLKDIV & 0xffU) + 1U);
956 }
957 
958 /* Set FRG Clk */
959 /**
960  * brief	Set the frg output frequency.
961  * param	freq	: output frequency
962  * return	0   : the frequency range is out of range.
963  *          1   : switch successfully.
964  */
CLOCK_SetFRGClock(uint32_t freq)965 uint32_t CLOCK_SetFRGClock(uint32_t freq)
966 {
967     assert(0U != freq);
968 
969     uint32_t input = CLOCK_GetFRGInputClock();
970     uint32_t mul;
971     uint32_t ret;
972 
973     if ((freq > 48000000U) || (freq > input) || (input / freq >= 2U))
974     {
975         /* FRG output frequency should be less than equal to 48MHz */
976         ret = 0U;
977     }
978     else
979     {
980         mul             = (uint32_t)((((uint64_t)input - freq) * 256ULL) / ((uint64_t)freq));
981         SYSCON->FRGCTRL = (mul << SYSCON_FRGCTRL_MULT_SHIFT) | SYSCON_FRGCTRL_DIV_MASK;
982         ret             = 1U;
983     }
984 
985     return ret;
986 }
987 
988 /* Set IP Clk */
989 /*! brief	Return Frequency of selected clock
990  *  return	Frequency of selected clock
991  */
CLOCK_GetFreq(clock_name_t clockName)992 uint32_t CLOCK_GetFreq(clock_name_t clockName)
993 {
994     uint32_t freq;
995     switch (clockName)
996     {
997         case kCLOCK_CoreSysClk:
998             freq = CLOCK_GetCoreSysClkFreq();
999             break;
1000         case kCLOCK_BusClk:
1001             freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
1002             break;
1003         case kCLOCK_ClockOut:
1004             freq = CLOCK_GetClockOutClkFreq();
1005             break;
1006         case kCLOCK_Mclk:
1007             freq = CLOCK_GetMclkClkFreq();
1008             break;
1009         case kCLOCK_FroHf:
1010             freq = CLOCK_GetFroHfFreq();
1011             break;
1012         case kCLOCK_Fro12M:
1013             freq = CLOCK_GetFro12MFreq();
1014             break;
1015         case kCLOCK_ExtClk:
1016             freq = CLOCK_GetExtClkFreq();
1017             break;
1018         case kCLOCK_PllOut:
1019             freq = CLOCK_GetPllOutFreq();
1020             break;
1021         case kCLOCK_WdtOsc:
1022             freq = CLOCK_GetWdtOscFreq();
1023             break;
1024         case kCLOCK_Frg:
1025             freq = CLOCK_GetFrgClkFreq();
1026             break;
1027 
1028         case kCLOCK_AsyncApbClk:
1029             freq = CLOCK_GetAsyncApbClkFreq();
1030             break;
1031         case kCLOCK_FlexI2S:
1032             freq = CLOCK_GetI2SMClkFreq();
1033             break;
1034         default:
1035             freq = 0U;
1036             break;
1037     }
1038 
1039     return freq;
1040 }
1041 
1042 /* Set the FLASH wait states for the passed frequency */
1043 /**
1044  * brief	Set the flash wait states for the input freuqency.
1045  * param	iFreq	: Input frequency
1046  * return	Nothing
1047  */
CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)1048 void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)
1049 {
1050     if (iFreq <= 12000000U)
1051     {
1052         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash1Cycle);
1053     }
1054     else if (iFreq <= 24000000U)
1055     {
1056         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash2Cycle);
1057     }
1058     else if (iFreq <= 36000000U)
1059     {
1060         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash3Cycle);
1061     }
1062     else if (iFreq <= 60000000U)
1063     {
1064         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash4Cycle);
1065     }
1066     else if (iFreq <= 96000000U)
1067     {
1068         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash5Cycle);
1069     }
1070     else if (iFreq <= 120000000U)
1071     {
1072         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash6Cycle);
1073     }
1074     else if (iFreq <= 144000000U)
1075     {
1076         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash7Cycle);
1077     }
1078     else if (iFreq <= 168000000U)
1079     {
1080         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash8Cycle);
1081     }
1082     else
1083     {
1084         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash9Cycle);
1085     }
1086 }
1087 
1088 /* Find encoded NDEC value for raw N value, max N = NVALMAX */
pllEncodeN(uint32_t N)1089 static uint32_t pllEncodeN(uint32_t N)
1090 {
1091     uint32_t x, i;
1092 
1093     /* Find NDec */
1094     switch (N)
1095     {
1096         case 0U:
1097             x = 0x3FFU;
1098             break;
1099 
1100         case 1U:
1101             x = 0x302U;
1102             break;
1103 
1104         case 2U:
1105             x = 0x202U;
1106             break;
1107 
1108         default:
1109             x = 0x080U;
1110             for (i = N; i <= NVALMAX; i++)
1111             {
1112                 x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
1113             }
1114             break;
1115     }
1116 
1117     return x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P);
1118 }
1119 
1120 /* Find decoded N value for raw NDEC value */
pllDecodeN(uint32_t NDEC)1121 static uint32_t pllDecodeN(uint32_t NDEC)
1122 {
1123     uint32_t n, x, i;
1124 
1125     /* Find NDec */
1126     switch (NDEC)
1127     {
1128         case 0x3FFU:
1129             n = 0U;
1130             break;
1131 
1132         case 0x302U:
1133             n = 1U;
1134             break;
1135 
1136         case 0x202U:
1137             n = 2U;
1138             break;
1139 
1140         default:
1141             x = 0x080U;
1142             n = 0xFFFFFFFFU;
1143             for (i = NVALMAX; (i >= 3U); i--)
1144             {
1145                 x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
1146                 if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC)
1147                 {
1148                     /* Decoded value of NDEC */
1149                     n = i;
1150                     break;
1151                 }
1152             }
1153             break;
1154     }
1155 
1156     return n;
1157 }
1158 
1159 /* Find encoded PDEC value for raw P value, max P = PVALMAX */
pllEncodeP(uint32_t P)1160 static uint32_t pllEncodeP(uint32_t P)
1161 {
1162     uint32_t x, i;
1163 
1164     /* Find PDec */
1165     switch (P)
1166     {
1167         case 0U:
1168             x = 0x7FU;
1169             break;
1170 
1171         case 1U:
1172             x = 0x62U;
1173             break;
1174 
1175         case 2U:
1176             x = 0x42U;
1177             break;
1178 
1179         default:
1180             x = 0x10U;
1181             for (i = P; i <= PVALMAX; i++)
1182             {
1183                 x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
1184             }
1185             break;
1186     }
1187 
1188     return x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P);
1189 }
1190 
1191 /* Find decoded P value for raw PDEC value */
pllDecodeP(uint32_t PDEC)1192 static uint32_t pllDecodeP(uint32_t PDEC)
1193 {
1194     uint32_t p, x, i;
1195 
1196     /* Find PDec */
1197     switch (PDEC)
1198     {
1199         case 0x7FU:
1200             p = 0U;
1201             break;
1202 
1203         case 0x62U:
1204             p = 1U;
1205             break;
1206 
1207         case 0x42U:
1208             p = 2U;
1209             break;
1210 
1211         default:
1212             x = 0x10U;
1213             p = 0xFFFFFFFFU;
1214             for (i = PVALMAX; (i >= 3U); i--)
1215             {
1216                 x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
1217                 if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC)
1218                 {
1219                     /* Decoded value of PDEC */
1220                     p = i;
1221                     break;
1222                 }
1223             }
1224             break;
1225     }
1226 
1227     return p;
1228 }
1229 
1230 /* Find encoded MDEC value for raw M value, max M = MVALMAX */
pllEncodeM(uint32_t M)1231 static uint32_t pllEncodeM(uint32_t M)
1232 {
1233     uint32_t i, x;
1234 
1235     /* Find MDec */
1236     switch (M)
1237     {
1238         case 0U:
1239             x = 0x1FFFFU;
1240             break;
1241 
1242         case 1U:
1243             x = 0x18003U;
1244             break;
1245 
1246         case 2U:
1247             x = 0x10003U;
1248             break;
1249 
1250         default:
1251             x = 0x04000U;
1252             for (i = M; i <= MVALMAX; i++)
1253             {
1254                 x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
1255             }
1256             break;
1257     }
1258 
1259     return x & (PLL_MDEC_VAL_M >> PLL_MDEC_VAL_P);
1260 }
1261 
1262 /* Find decoded M value for raw MDEC value */
pllDecodeM(uint32_t MDEC)1263 static uint32_t pllDecodeM(uint32_t MDEC)
1264 {
1265     uint32_t m, i, x;
1266 
1267     /* Find MDec */
1268     switch (MDEC)
1269     {
1270         case 0x1FFFFU:
1271             m = 0U;
1272             break;
1273 
1274         case 0x18003U:
1275             m = 1U;
1276             break;
1277 
1278         case 0x10003U:
1279             m = 2U;
1280             break;
1281 
1282         default:
1283             x = 0x04000U;
1284             m = 0xFFFFFFFFU;
1285             for (i = MVALMAX; (i >= 3U); i--)
1286             {
1287                 x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
1288                 if ((x & (PLL_MDEC_VAL_M >> PLL_MDEC_VAL_P)) == MDEC)
1289                 {
1290                     /* Decoded value of MDEC */
1291                     m = i;
1292                     break;
1293                 }
1294             }
1295             break;
1296     }
1297 
1298     return m;
1299 }
1300 
1301 /* 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)1302 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
1303 {
1304     /* bandwidth: compute selP from Multiplier */
1305     if (M < 60U)
1306     {
1307         *pSelP = (M >> 1U) + 1U;
1308     }
1309     else
1310     {
1311         *pSelP = PVALMAX - 1U;
1312     }
1313 
1314     /* bandwidth: compute selI from Multiplier */
1315     if (M > 16384U)
1316     {
1317         *pSelI = 1U;
1318     }
1319     else if (M > 8192U)
1320     {
1321         *pSelI = 2U;
1322     }
1323     else if (M > 2048U)
1324     {
1325         *pSelI = 4U;
1326     }
1327     else if (M >= 501U)
1328     {
1329         *pSelI = 8U;
1330     }
1331     else if (M >= 60U)
1332     {
1333         *pSelI = 4U * (1024U / (M + 9U));
1334     }
1335     else
1336     {
1337         *pSelI = (M & 0x3CU) + 4U;
1338     }
1339 
1340     if (*pSelI > ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT))
1341     {
1342         *pSelI = ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT);
1343     }
1344 
1345     *pSelR = 0U;
1346 }
1347 
1348 /* Get predivider (N) from PLL NDEC setting */
findPllPreDiv(uint32_t ctrlReg,uint32_t nDecReg)1349 static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg)
1350 {
1351     uint32_t preDiv = 1;
1352 
1353     /* Direct input is not used? */
1354     if ((ctrlReg & (1UL << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) == 0U)
1355     {
1356         /* Decode NDEC value to get (N) pre divider */
1357         preDiv = pllDecodeN(nDecReg & 0x3FFU);
1358         if (preDiv == 0U)
1359         {
1360             preDiv = 1U;
1361         }
1362     }
1363 
1364     /* Adjusted by 1, directi is used to bypass */
1365     return preDiv;
1366 }
1367 
1368 /* Get postdivider (P) from PLL PDEC setting */
findPllPostDiv(uint32_t ctrlReg,uint32_t pDecReg)1369 static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg)
1370 {
1371     uint32_t postDiv = 1U;
1372 
1373     /* Direct input is not used? */
1374     if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTO_MASK) == 0U)
1375     {
1376         /* Decode PDEC value to get (P) post divider */
1377         postDiv = 2U * pllDecodeP(pDecReg & 0x7FU);
1378         if (postDiv == 0U)
1379         {
1380             postDiv = 2U;
1381         }
1382     }
1383 
1384     /* Adjusted by 1, directo is used to bypass */
1385     return postDiv;
1386 }
1387 
1388 /* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
findPllMMult(uint32_t ctrlReg,uint32_t mDecReg)1389 static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg)
1390 {
1391     uint32_t mMult = 1U;
1392 
1393     /* Decode MDEC value to get (M) multiplier */
1394     mMult = pllDecodeM(mDecReg & 0x1FFFFU);
1395 
1396     if (mMult == 0U)
1397     {
1398         mMult = 1U;
1399     }
1400 
1401     return mMult;
1402 }
1403 
1404 /* Convert the binary to fractional part */
Binary2Fractional(uint32_t binaryPart)1405 static double Binary2Fractional(uint32_t binaryPart)
1406 {
1407     double fractional = 0.0;
1408     for (uint32_t i = 0U; i <= 14U; i++)
1409     {
1410         fractional += (double)(uint32_t)((binaryPart >> i) & 0x1UL) / (double)(uint32_t)(1UL << (15U - i));
1411     }
1412     return fractional;
1413 }
1414 
1415 /* Find greatest common divisor between m and n */
FindGreatestCommonDivisor(uint32_t m,uint32_t n)1416 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
1417 {
1418     uint32_t tmp;
1419 
1420     while (n != 0U)
1421     {
1422         tmp = n;
1423         n   = m % n;
1424         m   = tmp;
1425     }
1426 
1427     return m;
1428 }
1429 
1430 /*
1431  * Set PLL output based on desired output rate.
1432  * In this function, the it calculates the PLL setting for output frequency from input clock
1433  * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
1434  * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
1435  */
CLOCK_GetPllConfigInternal(uint32_t finHz,uint32_t foutHz,pll_setup_t * pSetup)1436 static pll_error_t CLOCK_GetPllConfigInternal(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup)
1437 {
1438     uint32_t nDivOutHz, fccoHz, multFccoDiv;
1439     uint32_t pllPreDivider, pllMultiplier, pllPostDivider;
1440     uint32_t pllDirectInput, pllDirectOutput;
1441     uint32_t pllSelP, pllSelI, pllSelR, uplimoff;
1442 
1443     /* Baseline parameters (no input or output dividers) */
1444     pllPreDivider   = 1U; /* 1 implies pre-divider will be disabled */
1445     pllPostDivider  = 0U; /* 0 implies post-divider will be disabled */
1446     pllDirectOutput = 1U;
1447     multFccoDiv     = 2U;
1448 
1449     /* Verify output rate parameter */
1450     if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
1451     {
1452         /* Maximum PLL output with post divider=1 cannot go above this frequency */
1453         return kStatus_PLL_OutputTooHigh;
1454     }
1455     if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
1456     {
1457         /* Minmum PLL output with maximum post divider cannot go below this frequency */
1458         return kStatus_PLL_OutputTooLow;
1459     }
1460 
1461     /* Verify input rate parameter */
1462     if (finHz < PLL_LOWER_IN_LIMIT)
1463     {
1464         /* Input clock into the PLL cannot be lower than this */
1465         return kStatus_PLL_InputTooLow;
1466     }
1467 
1468     /* Find the optimal CCO frequency for the output and input that
1469        will keep it inside the PLL CCO range. This may require
1470        tweaking the post-divider for the PLL. */
1471     fccoHz = foutHz;
1472     while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
1473     {
1474         /* CCO output is less than minimum CCO range, so the CCO output
1475            needs to be bumped up and the post-divider is used to bring
1476            the PLL output back down. */
1477         pllPostDivider++;
1478         if (pllPostDivider > PVALMAX)
1479         {
1480             return kStatus_PLL_OutsideIntLimit;
1481         }
1482 
1483         /* Target CCO goes up, PLL output goes down */
1484         fccoHz          = foutHz * (pllPostDivider * 2U);
1485         pllDirectOutput = 0U;
1486     }
1487 
1488     /* Determine if a pre-divider is needed to get the best frequency */
1489     if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz))
1490     {
1491         uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz));
1492 
1493         if (a > 20000U)
1494         {
1495             a = (multFccoDiv * finHz) / a;
1496             if ((a != 0U) && (a < PLL_MAX_N_DIV))
1497             {
1498                 pllPreDivider = a;
1499             }
1500         }
1501     }
1502 
1503     /* Bypass pre-divider hardware if pre-divider is 1 */
1504     if (pllPreDivider > 1U)
1505     {
1506         pllDirectInput = 0U;
1507     }
1508     else
1509     {
1510         pllDirectInput = 1U;
1511     }
1512 
1513     /* Determine PLL multipler */
1514     nDivOutHz     = (finHz / pllPreDivider);
1515     pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv;
1516 
1517     /* Find optimal values for filter */
1518     /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
1519     if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
1520     {
1521         pllMultiplier++;
1522     }
1523 
1524     /* Setup filtering */
1525     pllFindSel(pllMultiplier, &pllSelP, &pllSelI, &pllSelR);
1526     uplimoff = 0U;
1527 
1528     /* Get encoded value for M (mult) and use manual filter, disable SS mode */
1529     pSetup->pllmdec = PLL_MDEC_VAL_SET(pllEncodeM(pllMultiplier));
1530 
1531     /* Get encoded values for N (prediv) and P (postdiv) */
1532     pSetup->pllndec = PLL_NDEC_VAL_SET(pllEncodeN(pllPreDivider));
1533     pSetup->pllpdec = PLL_PDEC_VAL_SET(pllEncodeP(pllPostDivider));
1534 
1535     /* PLL control */
1536     pSetup->pllctrl = (pllSelR << SYSCON_SYSPLLCTRL_SELR_SHIFT) |           /* Filter coefficient */
1537                       (pllSelI << SYSCON_SYSPLLCTRL_SELI_SHIFT) |           /* Filter coefficient */
1538                       (pllSelP << SYSCON_SYSPLLCTRL_SELP_SHIFT) |           /* Filter coefficient */
1539                       (0UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT) |             /* PLL bypass mode disabled */
1540                       (uplimoff << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT) |      /* SS/fractional mode disabled */
1541                       (pllDirectInput << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT) | /* Bypass pre-divider? */
1542                       (pllDirectOutput << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT); /* Bypass post-divider? */
1543 
1544     return kStatus_PLL_Success;
1545 }
1546 
1547 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1548 /* Alloct the static buffer for cache. */
1549 static pll_setup_t s_PllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
1550 static uint32_t s_FinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT]  = {0};
1551 static uint32_t s_FoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
1552 static uint32_t s_PllSetupCacheIdx                                  = 0U;
1553 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1554 
1555 /*
1556  * Calculate the PLL setting values from input clock freq to output freq.
1557  */
CLOCK_GetPllConfig(uint32_t finHz,uint32_t foutHz,pll_setup_t * pSetup)1558 static pll_error_t CLOCK_GetPllConfig(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup)
1559 {
1560     pll_error_t retErr;
1561 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1562     uint32_t i;
1563 
1564     for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
1565     {
1566         if ((finHz == s_FinHzCache[i]) && (foutHz == s_FoutHzCache[i]))
1567         {
1568             /* Hit the target in cache buffer. */
1569             pSetup->pllctrl = s_PllSetupCacheStruct[i].pllctrl;
1570             pSetup->pllndec = s_PllSetupCacheStruct[i].pllndec;
1571             pSetup->pllpdec = s_PllSetupCacheStruct[i].pllpdec;
1572             pSetup->pllmdec = s_PllSetupCacheStruct[i].pllmdec;
1573             retErr          = kStatus_PLL_Success;
1574             break;
1575         }
1576     }
1577 
1578     if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1579     {
1580         return retErr;
1581     }
1582 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1583 
1584     /* No cache or did not hit the cache. */
1585     retErr = CLOCK_GetPllConfigInternal(finHz, foutHz, pSetup);
1586 
1587 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1588     if (kStatus_PLL_Success == retErr)
1589     {
1590         /* Cache the most recent calulation result into buffer. */
1591         s_FinHzCache[s_PllSetupCacheIdx]  = finHz;
1592         s_FoutHzCache[s_PllSetupCacheIdx] = foutHz;
1593 
1594         s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllctrl = pSetup->pllctrl;
1595         s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllndec = pSetup->pllndec;
1596         s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllpdec = pSetup->pllpdec;
1597         s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllmdec = pSetup->pllmdec;
1598         /* Update the index for next available buffer. */
1599         s_PllSetupCacheIdx = (s_PllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
1600     }
1601 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1602 
1603     return retErr;
1604 }
1605 
1606 /* Update SYSTEM PLL rate variable */
CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t * pSetup)1607 static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup)
1608 {
1609     s_Pll_Freq = CLOCK_GetSystemPLLOutFromSetup(pSetup);
1610 }
1611 
1612 /* Update AUDIO PLL rate variable */
CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t * pSetup)1613 static void CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t *pSetup)
1614 {
1615     s_Audio_Pll_Freq = CLOCK_GetAudioPLLOutFromSetup(pSetup);
1616 }
1617 
1618 /* Update AUDIO Fractional PLL rate variable */
CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pll_setup_t * pSetup)1619 static void CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pll_setup_t *pSetup)
1620 {
1621     s_Audio_Pll_Freq = CLOCK_GetAudioPLLOutFromFractSetup(pSetup);
1622 }
1623 
1624 /* Update USB PLL rate variable */
CLOCK_GetUsbPLLOutFromSetupUpdate(const usb_pll_setup_t * pSetup)1625 static void CLOCK_GetUsbPLLOutFromSetupUpdate(const usb_pll_setup_t *pSetup)
1626 {
1627     s_Usb_Pll_Freq = CLOCK_GetUsbPLLOutFromSetup(pSetup);
1628 }
1629 
1630 /* Return System PLL input clock rate */
1631 /*! brief	Return System PLL input clock rate
1632  *  return	System PLL input clock rate
1633  */
CLOCK_GetSystemPLLInClockRate(void)1634 uint32_t CLOCK_GetSystemPLLInClockRate(void)
1635 {
1636     uint32_t clkRate = 0U;
1637 
1638     switch ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK))
1639     {
1640         case 0x00U:
1641             clkRate = CLK_FRO_12MHZ;
1642             break;
1643 
1644         case 0x01U:
1645             clkRate = CLOCK_GetExtClkFreq();
1646             break;
1647 
1648         case 0x02U:
1649             clkRate = CLOCK_GetWdtOscFreq();
1650             break;
1651 
1652         case 0x03U:
1653             clkRate = CLOCK_GetOsc32KFreq();
1654             break;
1655 
1656         default:
1657             clkRate = 0U;
1658             break;
1659     }
1660 
1661     return clkRate;
1662 }
1663 
1664 /* Return Audio PLL input clock rate */
1665 /*! brief	Return Audio PLL input clock rate
1666  *  return	Audio PLL input clock rate
1667  */
CLOCK_GetAudioPLLInClockRate(void)1668 uint32_t CLOCK_GetAudioPLLInClockRate(void)
1669 {
1670     uint32_t clkRate = 0U;
1671 
1672     switch ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK))
1673     {
1674         case 0x00U:
1675             clkRate = CLK_FRO_12MHZ;
1676             break;
1677 
1678         case 0x01U:
1679             clkRate = CLOCK_GetExtClkFreq();
1680             break;
1681 
1682         default:
1683             clkRate = 0U;
1684             break;
1685     }
1686 
1687     return clkRate;
1688 }
1689 
1690 /* Return System PLL output clock rate from setup structure */
1691 /*! brief	Return System PLL output clock rate from setup structure
1692  *  param	pSetup	: Pointer to a PLL setup structure
1693  *  return	System PLL output clock rate the setup structure will generate
1694  */
CLOCK_GetSystemPLLOutFromSetup(pll_setup_t * pSetup)1695 uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup)
1696 {
1697     uint32_t prediv, postdiv, mMult, inPllRate;
1698     uint64_t workRate;
1699 
1700     inPllRate = CLOCK_GetSystemPLLInClockRate();
1701     /* If the PLL is bypassed, PLL would not be used and the output of PLL module would just be the input clock*/
1702     if ((pSetup->pllctrl & (SYSCON_SYSPLLCTRL_BYPASS_MASK)) == 0U)
1703     {
1704         /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
1705         /*
1706          * 1. Pre-divider
1707          * Pre-divider is only available when the DIRECTI is disabled.
1708          */
1709         if (0U == (pSetup->pllctrl & SYSCON_SYSPLLCTRL_DIRECTI_MASK))
1710         {
1711             prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
1712         }
1713         else
1714         {
1715             prediv = 1U; /* The pre-divider is bypassed. */
1716         }
1717         /*
1718          * 2. Post-divider
1719          * Post-divider is only available when the DIRECTO is disabled.
1720          */
1721         if (0U == (pSetup->pllctrl & SYSCON_SYSPLLCTRL_DIRECTO_MASK))
1722         {
1723             postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
1724         }
1725         else
1726         {
1727             postdiv = 1U; /* The post-divider is bypassed. */
1728         }
1729         /* Adjust input clock */
1730         inPllRate = inPllRate / prediv;
1731 
1732         /* MDEC used for rate */
1733         mMult    = findPllMMult(pSetup->pllctrl, pSetup->pllmdec);
1734         workRate = (uint64_t)inPllRate * (uint64_t)mMult;
1735 
1736         workRate = workRate / ((uint64_t)postdiv);
1737         workRate = workRate * 2U; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
1738     }
1739     else
1740     {
1741         /* In bypass mode */
1742         workRate = (uint64_t)inPllRate;
1743     }
1744 
1745     return (uint32_t)workRate;
1746 }
1747 
1748 /* Return Usb PLL output clock rate from setup structure */
1749 /*! brief	Return System USB PLL output clock rate from setup structure
1750  *  param	pSetup	: Pointer to a PLL setup structure
1751  *  return	System PLL output clock rate the setup structure will generate
1752  */
CLOCK_GetUsbPLLOutFromSetup(const usb_pll_setup_t * pSetup)1753 uint32_t CLOCK_GetUsbPLLOutFromSetup(const usb_pll_setup_t *pSetup)
1754 {
1755     uint32_t nsel, psel, msel, inPllRate;
1756     uint64_t workRate;
1757     inPllRate = CLOCK_GetExtClkFreq();
1758     msel      = pSetup->msel;
1759     psel      = pSetup->psel;
1760     nsel      = pSetup->nsel;
1761 
1762     if (pSetup->fbsel)
1763     {
1764         /*integer_mode: Fout = M*(Fin/N),  Fcco = 2*P*M*(Fin/N) */
1765         workRate = (uint64_t)(inPllRate) * (msel + 1ULL) / (nsel + 1ULL);
1766     }
1767     else
1768     {
1769         /* non integer_mode: Fout = M*(Fin/N)/(2*P), Fcco = M * (Fin/N) */
1770         workRate = ((uint64_t)inPllRate / (nsel + 1ULL)) * (msel + 1ULL) / (2U * (1UL << (psel & 3U)));
1771     }
1772 
1773     return (uint32_t)workRate;
1774 }
1775 
1776 /* Return Audio PLL output clock rate from setup structure */
1777 /*! brief	Return System AUDIO PLL output clock rate from setup structure
1778  *  param	pSetup	: Pointer to a PLL setup structure
1779  *  return	System PLL output clock rate the setup structure will generate
1780  */
CLOCK_GetAudioPLLOutFromSetup(pll_setup_t * pSetup)1781 uint32_t CLOCK_GetAudioPLLOutFromSetup(pll_setup_t *pSetup)
1782 {
1783     uint32_t prediv, postdiv, mMult, inPllRate;
1784     uint64_t workRate;
1785 
1786     inPllRate = CLOCK_GetAudioPLLInClockRate();
1787     if ((pSetup->pllctrl & (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) == 0U)
1788     {
1789         /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
1790         /*
1791          * 1. Pre-divider
1792          * Pre-divider is only available when the DIRECTI is disabled.
1793          */
1794         if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTI_MASK))
1795         {
1796             prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
1797         }
1798         else
1799         {
1800             prediv = 1U; /* The pre-divider is bypassed. */
1801         }
1802         /*
1803          * 2. Post-divider
1804          * Post-divider is only available when the DIRECTO is disabled.
1805          */
1806         if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTO_MASK))
1807         {
1808             postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
1809         }
1810         else
1811         {
1812             postdiv = 1U; /* The post-divider is bypassed. */
1813         }
1814         /* Adjust input clock */
1815         inPllRate = inPllRate / prediv;
1816 
1817         /* MDEC used for rate */
1818         mMult    = findPllMMult(pSetup->pllctrl, pSetup->pllmdec);
1819         workRate = (uint64_t)inPllRate * (uint64_t)mMult;
1820 
1821         workRate = workRate / ((uint64_t)postdiv);
1822         workRate = workRate * 2U; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
1823     }
1824     else
1825     {
1826         /* In bypass mode */
1827         workRate = (uint64_t)inPllRate;
1828     }
1829 
1830     return (uint32_t)workRate;
1831 }
1832 
1833 /* Return Audio PLL output clock rate from audio fractioanl setup structure */
1834 /*! brief	Return System AUDIO PLL output clock rate from audio fractioanl setup structure
1835  *  param	pSetup	: Pointer to a PLL setup structure
1836  *  return	System PLL output clock rate the setup structure will generate
1837  */
CLOCK_GetAudioPLLOutFromFractSetup(pll_setup_t * pSetup)1838 uint32_t CLOCK_GetAudioPLLOutFromFractSetup(pll_setup_t *pSetup)
1839 {
1840     uint32_t prediv, postdiv, inPllRate;
1841     double workRate, mMultFactional;
1842 
1843     inPllRate = CLOCK_GetAudioPLLInClockRate();
1844     if ((pSetup->pllctrl & (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) == 0U)
1845     {
1846         /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
1847         /*
1848          * 1. Pre-divider
1849          * Pre-divider is only available when the DIRECTI is disabled.
1850          */
1851         if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTI_MASK))
1852         {
1853             prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
1854         }
1855         else
1856         {
1857             prediv = 1U; /* The pre-divider is bypassed. */
1858         }
1859         /*
1860          * 2. Post-divider
1861          * Post-divider is only available when the DIRECTO is disabled.
1862          */
1863         if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTO_MASK))
1864         {
1865             postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
1866         }
1867         else
1868         {
1869             postdiv = 1U; /* The post-divider is bypassed. */
1870         }
1871         /* Adjust input clock */
1872         inPllRate = inPllRate / prediv;
1873 
1874         mMultFactional =
1875             (double)(uint32_t)(pSetup->audpllfrac >> 15U) + (double)Binary2Fractional(pSetup->audpllfrac & 0x7FFFU);
1876         workRate = (double)inPllRate * (double)mMultFactional;
1877 
1878         workRate = workRate / ((double)postdiv);
1879         workRate = workRate * 2.0; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
1880     }
1881     else
1882     {
1883         /* In bypass mode */
1884         workRate = (double)inPllRate;
1885     }
1886 
1887     return (uint32_t)workRate;
1888 }
1889 
1890 /* Set the current PLL Rate */
1891 /*! brief Store the current PLL rate
1892  *  param	rate: Current rate of the PLL
1893  *  return	Nothing
1894  **/
CLOCK_SetStoredPLLClockRate(uint32_t rate)1895 void CLOCK_SetStoredPLLClockRate(uint32_t rate)
1896 {
1897     s_Pll_Freq = rate;
1898 }
1899 
1900 /* Set the current Audio PLL Rate */
1901 /*! brief Store the current AUDIO PLL rate
1902  *  param	rate: Current rate of the PLL
1903  *  return	Nothing
1904  **/
CLOCK_SetStoredAudioPLLClockRate(uint32_t rate)1905 void CLOCK_SetStoredAudioPLLClockRate(uint32_t rate)
1906 {
1907     s_Audio_Pll_Freq = rate;
1908 }
1909 
1910 /* Set the current Usb PLL Rate */
1911 /*! brief	Set USB PLL output frequency
1912  *  param	rate		: frequency value
1913  *
1914  */
CLOCK_SetStoredUsbPLLClockRate(uint32_t rate)1915 void CLOCK_SetStoredUsbPLLClockRate(uint32_t rate)
1916 {
1917     s_Usb_Pll_Freq = rate;
1918 }
1919 
1920 /* Return System PLL output clock rate */
1921 /*! brief	Return System PLL output clock rate
1922  *  param	recompute	: Forces a PLL rate recomputation if true
1923  *  return	System PLL output clock rate
1924  *  note	The PLL rate is cached in the driver in a variable as
1925  *  the rate computation function can take some time to perform. It
1926  *  is recommended to use 'false' with the 'recompute' parameter.
1927  */
CLOCK_GetSystemPLLOutClockRate(bool recompute)1928 uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute)
1929 {
1930     pll_setup_t Setup;
1931     uint32_t rate;
1932 
1933     if ((recompute) || (s_Pll_Freq == 0U))
1934     {
1935         Setup.pllctrl = SYSCON->SYSPLLCTRL;
1936         Setup.pllndec = SYSCON->SYSPLLNDEC;
1937         Setup.pllpdec = SYSCON->SYSPLLPDEC;
1938         Setup.pllmdec = SYSCON->SYSPLLMDEC;
1939 
1940         CLOCK_GetSystemPLLOutFromSetupUpdate(&Setup);
1941     }
1942 
1943     rate = s_Pll_Freq;
1944 
1945     return rate;
1946 }
1947 
1948 /* Return AUDIO PLL output clock rate */
1949 /*! brief	Return System AUDIO PLL output clock rate
1950  *  param	recompute	: Forces a AUDIO PLL rate recomputation if true
1951  *  return	System AUDIO PLL output clock rate
1952  *  note	The AUDIO PLL rate is cached in the driver in a variable as
1953  *  the rate computation function can take some time to perform. It
1954  *  is recommended to use 'false' with the 'recompute' parameter.
1955  */
CLOCK_GetAudioPLLOutClockRate(bool recompute)1956 uint32_t CLOCK_GetAudioPLLOutClockRate(bool recompute)
1957 {
1958     pll_setup_t Setup;
1959     uint32_t rate;
1960 
1961     if ((recompute) || (s_Audio_Pll_Freq == 0U))
1962     {
1963         Setup.pllctrl = SYSCON->AUDPLLCTRL;
1964         Setup.pllndec = SYSCON->AUDPLLNDEC;
1965         Setup.pllpdec = SYSCON->AUDPLLPDEC;
1966         Setup.pllmdec = SYSCON->AUDPLLMDEC;
1967 
1968         CLOCK_GetAudioPLLOutFromSetupUpdate(&Setup);
1969     }
1970 
1971     rate = s_Audio_Pll_Freq;
1972     return rate;
1973 }
1974 
1975 /* Return USB PLL output clock rate */
1976 /*! brief	Return System USB PLL output clock rate
1977  *  param	recompute	: Forces a USB PLL rate recomputation if true
1978  *  return	System USB PLL output clock rate
1979  *  note	The USB PLL rate is cached in the driver in a variable as
1980  *  the rate computation function can take some time to perform. It
1981  *  is recommended to use 'false' with the 'recompute' parameter.
1982  */
CLOCK_GetUsbPLLOutClockRate(bool recompute)1983 uint32_t CLOCK_GetUsbPLLOutClockRate(bool recompute)
1984 {
1985     usb_pll_setup_t Setup;
1986     uint32_t rate;
1987     uint32_t usbPllCtrl;
1988 
1989     if ((recompute) || (s_Usb_Pll_Freq == 0U))
1990     {
1991         usbPllCtrl   = SYSCON->USBPLLCTRL;
1992         Setup.msel   = (uint8_t)((usbPllCtrl & SYSCON_USBPLLCTRL_MSEL_MASK) >> SYSCON_USBPLLCTRL_MSEL_SHIFT);
1993         Setup.psel   = (uint8_t)((usbPllCtrl & SYSCON_USBPLLCTRL_PSEL_MASK) >> SYSCON_USBPLLCTRL_PSEL_SHIFT);
1994         Setup.nsel   = (uint8_t)((usbPllCtrl & SYSCON_USBPLLCTRL_NSEL_MASK) >> SYSCON_USBPLLCTRL_NSEL_SHIFT);
1995         Setup.fbsel  = (0U != (usbPllCtrl & SYSCON_USBPLLCTRL_FBSEL_MASK));
1996         Setup.bypass = (0U != (usbPllCtrl & SYSCON_USBPLLCTRL_BYPASS_MASK));
1997         Setup.direct = (0U != (usbPllCtrl & SYSCON_USBPLLCTRL_DIRECT_MASK));
1998         CLOCK_GetUsbPLLOutFromSetupUpdate(&Setup);
1999     }
2000 
2001     rate = s_Usb_Pll_Freq;
2002     return rate;
2003 }
2004 
2005 /* Set PLL output based on the passed PLL setup data */
2006 /*! brief	Set PLL output based on the passed PLL setup data
2007  *  param	pControl	: Pointer to populated PLL control structure to generate setup with
2008  *  param	pSetup		: Pointer to PLL setup structure to be filled
2009  *  return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2010  *  note	Actual frequency for setup may vary from the desired frequency based on the
2011  *  accuracy of input clocks, rounding, non-fractional PLL mode, etc.
2012  */
CLOCK_SetupPLLData(pll_config_t * pControl,pll_setup_t * pSetup)2013 pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
2014 {
2015     uint32_t inRate;
2016     pll_error_t pllError;
2017 
2018     /* Determine input rate for the PLL */
2019     if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
2020     {
2021         inRate = pControl->inputRate;
2022     }
2023     else
2024     {
2025         inRate = CLOCK_GetSystemPLLInClockRate();
2026     }
2027 
2028     /* PLL flag options */
2029     pllError        = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup);
2030     pSetup->pllRate = pControl->desiredRate;
2031     return pllError;
2032 }
2033 
2034 /* Set PLL output from PLL setup structure */
2035 /*! brief	Set PLL output from PLL setup structure (precise frequency)
2036  * param	pSetup	: Pointer to populated PLL setup structure
2037  * param flagcfg : Flag configuration for PLL config structure
2038  * return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2039  * note	This function will power off the PLL, setup the PLL with the
2040  * new setup data, and then optionally powerup the PLL, wait for PLL lock,
2041  * and adjust system voltages to the new PLL rate. The function will not
2042  * alter any source clocks (ie, main systen clock) that may use the PLL,
2043  * so these should be setup prior to and after exiting the function.
2044  */
CLOCK_SetupSystemPLLPrec(pll_setup_t * pSetup,uint32_t flagcfg)2045 pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
2046 {
2047     if ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) == 0x01U)
2048     {
2049         /* Turn on the ext clock if system pll input select clk_in */
2050         CLOCK_Enable_SysOsc(true);
2051     }
2052     /* Enable power for PLLs */
2053     POWER_SetPLL();
2054     /* Power off PLL during setup changes */
2055     POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
2056     /*!< Set FLASH waitstates for core */
2057     CLOCK_SetFLASHAccessCyclesForFreq(pSetup->pllRate);
2058     pSetup->flags = flagcfg;
2059 
2060     /* Write PLL setup data */
2061     SYSCON->SYSPLLCTRL = pSetup->pllctrl;
2062     SYSCON->SYSPLLNDEC = pSetup->pllndec;
2063     SYSCON->SYSPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
2064     SYSCON->SYSPLLPDEC = pSetup->pllpdec;
2065     SYSCON->SYSPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
2066     SYSCON->SYSPLLMDEC = pSetup->pllmdec;
2067     SYSCON->SYSPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
2068 
2069     /* Flags for lock or power on */
2070     if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
2071     {
2072         /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
2073         uint32_t maxCCO    = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
2074         uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
2075 
2076         /* Initialize  and power up PLL */
2077         SYSCON->SYSPLLMDEC = maxCCO;
2078         POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
2079 
2080         /* Set mreq to activate */
2081         SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
2082 
2083         /* Delay for 72 uSec @ 12Mhz */
2084         SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2085 
2086         /* clear mreq to prepare for restoring mreq */
2087         SYSCON->SYSPLLMDEC = curSSCTRL;
2088 
2089         /* set original value back and activate */
2090         SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
2091 
2092         /* Enable peripheral states by setting low */
2093         POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
2094     }
2095     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2096     {
2097         while (CLOCK_IsSystemPLLLocked() == false)
2098         {
2099         }
2100     }
2101 
2102     /* Update current programmed PLL rate var */
2103     CLOCK_GetSystemPLLOutFromSetupUpdate(pSetup);
2104 
2105     /* System voltage adjustment, occurs prior to setting main system clock */
2106     if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0U)
2107     {
2108         POWER_SetVoltageForFreq(s_Pll_Freq);
2109     }
2110 
2111     return kStatus_PLL_Success;
2112 }
2113 
2114 /* Set AUDIO PLL output from AUDIO PLL setup structure */
2115 /*! brief	Set AUDIO PLL output from AUDIOPLL setup structure (precise frequency)
2116  * param	pSetup	: Pointer to populated PLL setup structure
2117  * param flagcfg : Flag configuration for PLL config structure
2118  * return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2119  * note	This function will power off the PLL, setup the PLL with the
2120  * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
2121  * and adjust system voltages to the new AUDIOPLL rate. The function will not
2122  * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
2123  * so these should be setup prior to and after exiting the function.
2124  */
CLOCK_SetupAudioPLLPrec(pll_setup_t * pSetup,uint32_t flagcfg)2125 pll_error_t CLOCK_SetupAudioPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
2126 {
2127     if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
2128     {
2129         /* Turn on the ext clock if system pll input select clk_in */
2130         CLOCK_Enable_SysOsc(true);
2131     }
2132     /* Enable power VD3 for PLLs */
2133     POWER_SetPLL();
2134     /* Power off PLL during setup changes */
2135     POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
2136 
2137     pSetup->flags = flagcfg;
2138 
2139     /* Write PLL setup data */
2140     SYSCON->AUDPLLCTRL = pSetup->pllctrl;
2141     SYSCON->AUDPLLNDEC = pSetup->pllndec;
2142     SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
2143     SYSCON->AUDPLLPDEC = pSetup->pllpdec;
2144     SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
2145     SYSCON->AUDPLLMDEC = pSetup->pllmdec;
2146     SYSCON->AUDPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
2147     SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(1);                            /* disable fractional function */
2148 
2149     /* Flags for lock or power on */
2150     if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
2151     {
2152         /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
2153         uint32_t maxCCO    = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
2154         uint32_t curSSCTRL = SYSCON->AUDPLLMDEC & ~(1UL << 17U);
2155 
2156         /* Initialize  and power up PLL */
2157         SYSCON->AUDPLLMDEC = maxCCO;
2158         POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2159 
2160         /* Set mreq to activate */
2161         SYSCON->AUDPLLMDEC = maxCCO | (1UL << 17U);
2162 
2163         /* Delay for 72 uSec @ 12Mhz */
2164         SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2165 
2166         /* clear mreq to prepare for restoring mreq */
2167         SYSCON->AUDPLLMDEC = curSSCTRL;
2168 
2169         /* set original value back and activate */
2170         SYSCON->AUDPLLMDEC = curSSCTRL | (1UL << 17U);
2171 
2172         /* Enable peripheral states by setting low */
2173         POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2174     }
2175     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2176     {
2177         while (CLOCK_IsAudioPLLLocked() == false)
2178         {
2179         }
2180     }
2181 
2182     /* Update current programmed PLL rate var */
2183     CLOCK_GetAudioPLLOutFromSetupUpdate(pSetup);
2184 
2185     return kStatus_PLL_Success;
2186 }
2187 
2188 /* Set AUDIO PLL output from AUDIO PLL fractional setup structure */
2189 /*! brief	Set AUDIO PLL output from AUDIOPLL setup structure using the Audio Fractional divider register(precise
2190  * frequency)
2191  * param	pSetup	: Pointer to populated PLL setup structure
2192  * param flagcfg : Flag configuration for PLL config structure
2193  * return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2194  * note	This function will power off the PLL, setup the PLL with the
2195  * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
2196  * and adjust system voltages to the new AUDIOPLL rate. The function will not
2197  * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
2198  * so these should be setup prior to and after exiting the function.
2199  */
CLOCK_SetupAudioPLLPrecFract(pll_setup_t * pSetup,uint32_t flagcfg)2200 pll_error_t CLOCK_SetupAudioPLLPrecFract(pll_setup_t *pSetup, uint32_t flagcfg)
2201 {
2202     if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
2203     {
2204         /* Turn on the ext clock if system pll input select clk_in */
2205         CLOCK_Enable_SysOsc(true);
2206     }
2207     /* Enable power VD3 for PLLs */
2208     POWER_SetPLL();
2209     /* Power off PLL during setup changes */
2210     POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
2211 
2212     pSetup->flags = flagcfg;
2213 
2214     /* Write PLL setup data */
2215     SYSCON->AUDPLLCTRL = pSetup->pllctrl;
2216     SYSCON->AUDPLLNDEC = pSetup->pllndec;
2217     SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
2218     SYSCON->AUDPLLPDEC = pSetup->pllpdec;
2219     SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
2220     SYSCON->AUDPLLMDEC = pSetup->pllmdec;
2221     SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(0); /* enable fractional function */
2222     SYSCON->AUDPLLFRAC = pSetup->audpllfrac;
2223     SYSCON->AUDPLLFRAC = pSetup->audpllfrac | (1UL << SYSCON_AUDPLLFRAC_REQ_SHIFT);
2224 
2225     /* Enable peripheral states by setting low */
2226     POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2227 
2228     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2229     {
2230         while (CLOCK_IsAudioPLLLocked() == false)
2231         {
2232         }
2233     }
2234 
2235     /* Update current programmed PLL rate var */
2236     CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pSetup);
2237 
2238     return kStatus_PLL_Success;
2239 }
2240 
2241 /* Set Audio PLL output based on the passed Audio PLL setup data */
2242 /*! brief	Set AUDIO PLL output based on the passed AUDIO PLL setup data
2243  *  param	pControl	: Pointer to populated PLL control structure to generate setup with
2244  *  param	pSetup		: Pointer to PLL setup structure to be filled
2245  *  return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2246  *  note	Actual frequency for setup may vary from the desired frequency based on the
2247  *  accuracy of input clocks, rounding, non-fractional PLL mode, etc.
2248  */
CLOCK_SetupAudioPLLData(pll_config_t * pControl,pll_setup_t * pSetup)2249 pll_error_t CLOCK_SetupAudioPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
2250 {
2251     uint32_t inRate;
2252     pll_error_t pllError;
2253 
2254     /* Determine input rate for the PLL */
2255     if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
2256     {
2257         inRate = pControl->inputRate;
2258     }
2259     else
2260     {
2261         inRate = CLOCK_GetAudioPLLInClockRate();
2262     }
2263 
2264     /* PLL flag options */
2265     pllError        = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup);
2266     pSetup->pllRate = pControl->desiredRate;
2267     return pllError;
2268 }
2269 
2270 /* Setup PLL Frequency from pre-calculated value */
2271 /**
2272  * brief	Set PLL output from PLL setup structure (precise frequency)
2273  * param	pSetup	: Pointer to populated PLL setup structure
2274  * return	kStatus_PLL_Success on success, or PLL setup error code
2275  * note	This function will power off the PLL, setup the PLL with the
2276  * new setup data, and then optionally powerup the PLL, wait for PLL lock,
2277  * and adjust system voltages to the new PLL rate. The function will not
2278  * alter any source clocks (ie, main systen clock) that may use the PLL,
2279  * so these should be setup prior to and after exiting the function.
2280  */
CLOCK_SetPLLFreq(const pll_setup_t * pSetup)2281 pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup)
2282 {
2283     if ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) == 0x01U)
2284     {
2285         /* Turn on the ext clock if system pll input select clk_in */
2286         CLOCK_Enable_SysOsc(true);
2287     }
2288     /* Enable power VD3 for PLLs */
2289     POWER_SetPLL();
2290     /* Power off PLL during setup changes */
2291     POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
2292 
2293     /* Write PLL setup data */
2294     SYSCON->SYSPLLCTRL = pSetup->pllctrl;
2295     SYSCON->SYSPLLNDEC = pSetup->pllndec;
2296     SYSCON->SYSPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
2297     SYSCON->SYSPLLPDEC = pSetup->pllpdec;
2298     SYSCON->SYSPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
2299     SYSCON->SYSPLLMDEC = pSetup->pllmdec;
2300     SYSCON->SYSPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
2301 
2302     /* Flags for lock or power on */
2303     if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
2304     {
2305         /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
2306         uint32_t maxCCO    = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
2307         uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
2308 
2309         /* Initialize  and power up PLL */
2310         SYSCON->SYSPLLMDEC = maxCCO;
2311         POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
2312 
2313         /* Set mreq to activate */
2314         SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
2315 
2316         /* Delay for 72 uSec @ 12Mhz */
2317         SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2318 
2319         /* clear mreq to prepare for restoring mreq */
2320         SYSCON->SYSPLLMDEC = curSSCTRL;
2321 
2322         /* set original value back and activate */
2323         SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
2324 
2325         /* Enable peripheral states by setting low */
2326         POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
2327     }
2328     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2329     {
2330         while (CLOCK_IsSystemPLLLocked() == false)
2331         {
2332         }
2333     }
2334 
2335     /* Update current programmed PLL rate var */
2336     s_Pll_Freq = pSetup->pllRate;
2337 
2338     return kStatus_PLL_Success;
2339 }
2340 
2341 /* Setup Audio PLL Frequency from pre-calculated value */
2342 /**
2343  * brief	Set Audio PLL output from Audio PLL setup structure (precise frequency)
2344  * param	pSetup	: Pointer to populated PLL setup structure
2345  * return	kStatus_PLL_Success on success, or Audio PLL setup error code
2346  * note	This function will power off the PLL, setup the Audio PLL with the
2347  * new setup data, and then optionally powerup the PLL, wait for Audio PLL lock,
2348  * and adjust system voltages to the new PLL rate. The function will not
2349  * alter any source clocks (ie, main systen clock) that may use the Audio PLL,
2350  * so these should be setup prior to and after exiting the function.
2351  */
CLOCK_SetAudioPLLFreq(const pll_setup_t * pSetup)2352 pll_error_t CLOCK_SetAudioPLLFreq(const pll_setup_t *pSetup)
2353 {
2354     if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
2355     {
2356         /* Turn on the ext clock if system pll input select clk_in */
2357         CLOCK_Enable_SysOsc(true);
2358     }
2359     /* Enable power VD3 for PLLs */
2360     POWER_SetPLL();
2361     /* Power off Audio PLL during setup changes */
2362     POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
2363 
2364     /* Write Audio PLL setup data */
2365     SYSCON->AUDPLLCTRL = pSetup->pllctrl;
2366     SYSCON->AUDPLLFRAC = pSetup->audpllfrac;
2367     SYSCON->AUDPLLFRAC = pSetup->audpllfrac | (1UL << SYSCON_AUDPLLFRAC_REQ_SHIFT); /* latch */
2368     SYSCON->AUDPLLNDEC = pSetup->pllndec;
2369     SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_AUDPLLNDEC_NREQ_SHIFT); /* latch */
2370     SYSCON->AUDPLLPDEC = pSetup->pllpdec;
2371     SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_AUDPLLPDEC_PREQ_SHIFT); /* latch */
2372     SYSCON->AUDPLLMDEC = pSetup->pllmdec;
2373     SYSCON->AUDPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_AUDPLLMDEC_MREQ_SHIFT); /* latch */
2374     SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(1);                            /* disable fractional function */
2375 
2376     /* Flags for lock or power on */
2377     if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
2378     {
2379         /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
2380         uint32_t maxCCO    = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
2381         uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
2382 
2383         /* Initialize  and power up PLL */
2384         SYSCON->SYSPLLMDEC = maxCCO;
2385         POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2386 
2387         /* Set mreq to activate */
2388         SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
2389 
2390         /* Delay for 72 uSec @ 12Mhz */
2391         SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2392 
2393         /* clear mreq to prepare for restoring mreq */
2394         SYSCON->SYSPLLMDEC = curSSCTRL;
2395 
2396         /* set original value back and activate */
2397         SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
2398 
2399         /* Enable peripheral states by setting low */
2400         POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2401     }
2402     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2403     {
2404         while (CLOCK_IsAudioPLLLocked() == false)
2405         {
2406         }
2407     }
2408 
2409     /* Update current programmed PLL rate var */
2410     s_Audio_Pll_Freq = pSetup->pllRate;
2411 
2412     return kStatus_PLL_Success;
2413 }
2414 
2415 /* Setup USB PLL Frequency from pre-calculated value */
2416 /**
2417  * brief	Set USB PLL output from USB PLL setup structure (precise frequency)
2418  * param	pSetup	: Pointer to populated USB PLL setup structure
2419  * return	kStatus_PLL_Success on success, or USB PLL setup error code
2420  * note	This function will power off the USB PLL, setup the PLL with the
2421  * new setup data, and then optionally powerup the USB PLL, wait for USB PLL lock,
2422  * and adjust system voltages to the new USB PLL rate. The function will not
2423  * alter any source clocks (ie, usb pll clock) that may use the USB PLL,
2424  * so these should be setup prior to and after exiting the function.
2425  */
CLOCK_SetUsbPLLFreq(const usb_pll_setup_t * pSetup)2426 pll_error_t CLOCK_SetUsbPLLFreq(const usb_pll_setup_t *pSetup)
2427 {
2428     uint32_t usbpllctrl, fccoHz;
2429     uint8_t msel, psel, nsel;
2430     bool pllDirectInput, pllDirectOutput, pllfbsel;
2431 
2432     msel            = pSetup->msel;
2433     psel            = pSetup->psel;
2434     nsel            = pSetup->nsel;
2435     pllDirectOutput = pSetup->direct;
2436     pllDirectInput  = pSetup->bypass;
2437     pllfbsel        = pSetup->fbsel;
2438 
2439     /* Input clock into the PLL cannot be lower than this */
2440     if (pSetup->inputRate < USB_PLL_LOWER_IN_LIMIT)
2441     {
2442         return kStatus_PLL_InputTooLow;
2443     }
2444 
2445     if (pllfbsel)
2446     {
2447         /*integer_mode: Fout = M*(Fin/N),  Fcco = 2*P*M*(Fin/N) */
2448         fccoHz = (pSetup->inputRate / (nsel + 1UL)) * 2UL * (msel + 1UL) * (1UL << (psel & 3U));
2449 
2450         /* USB PLL CCO out rate cannot be lower than this */
2451         if (fccoHz < USB_PLL_MIN_CCO_FREQ_MHZ)
2452         {
2453             return kStatus_PLL_CCOTooLow;
2454         }
2455         /* USB PLL CCO out rate cannot be Higher than this */
2456         if (fccoHz > USB_PLL_MAX_CCO_FREQ_MHZ)
2457         {
2458             return kStatus_PLL_CCOTooHigh;
2459         }
2460     }
2461     else
2462     {
2463         /* non integer_mode: Fout = M*(Fin/N)/(2*P), Fcco = M * (Fin/N) */
2464         fccoHz = pSetup->inputRate / (nsel + 1UL) * (msel + 1UL);
2465 
2466         /* USB PLL CCO out rate cannot be lower than this */
2467         if (fccoHz < USB_PLL_MIN_CCO_FREQ_MHZ)
2468         {
2469             return kStatus_PLL_CCOTooLow;
2470         }
2471         /* USB PLL CCO out rate cannot be Higher than this */
2472         if (fccoHz > USB_PLL_MAX_CCO_FREQ_MHZ)
2473         {
2474             return kStatus_PLL_CCOTooHigh;
2475         }
2476     }
2477 
2478     /* If configure the USB HOST clock, VD5 power for USB PHY should be enable
2479        before the PLL is working */
2480     /* Turn on the ext clock for usb pll input */
2481     CLOCK_Enable_SysOsc(true);
2482 
2483     /* Enable power VD3 for PLLs */
2484     POWER_SetPLL();
2485 
2486     /* Power on the VD5 for USB PHY */
2487     POWER_SetUsbPhy();
2488 
2489     /* Power off USB PLL during setup changes */
2490     POWER_EnablePD(kPDRUNCFG_PD_USB_PLL);
2491 
2492     /* Write USB PLL setup data */
2493     usbpllctrl = USB_PLL_NSEL_VAL_SET(nsel) |                                  /* NSEL VALUE */
2494                  USB_PLL_PSEL_VAL_SET(psel) |                                  /* PSEL VALUE */
2495                  USB_PLL_MSEL_VAL_SET(msel) |                                  /* MSEL VALUE */
2496                  (uint32_t)pllDirectInput << SYSCON_USBPLLCTRL_BYPASS_SHIFT |  /* BYPASS DISABLE */
2497                  (uint32_t)pllDirectOutput << SYSCON_USBPLLCTRL_DIRECT_SHIFT | /* DIRECTO DISABLE */
2498                  (uint32_t)pllfbsel << SYSCON_USBPLLCTRL_FBSEL_SHIFT;          /* FBSEL SELECT */
2499 
2500     SYSCON->USBPLLCTRL = usbpllctrl;
2501 
2502     POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
2503 
2504     /* Delay for 72 uSec @ 12Mhz for the usb pll to lock */
2505     SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2506     if (false == pllDirectInput)
2507     {
2508         while (CLOCK_IsUsbPLLLocked() == false)
2509         {
2510         }
2511     }
2512     CLOCK_GetUsbPLLOutFromSetupUpdate(pSetup);
2513     return kStatus_PLL_Success;
2514 }
2515 
2516 /* Set System PLL clock based on the input frequency and multiplier */
2517 /*! brief	Set PLL output based on the multiplier and input frequency
2518  * param	multiply_by	: multiplier
2519  * param	input_freq	: Clock input frequency of the PLL
2520  * return	Nothing
2521  * note	Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
2522  * function does not disable or enable PLL power, wait for PLL lock,
2523  * or adjust system voltages. These must be done in the application.
2524  * The function will not alter any source clocks (ie, main systen clock)
2525  * that may use the PLL, so these should be setup prior to and after
2526  * exiting the function.
2527  */
CLOCK_SetupSystemPLLMult(uint32_t multiply_by,uint32_t input_freq)2528 void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq)
2529 {
2530     uint32_t cco_freq = input_freq * multiply_by;
2531     uint32_t pdec     = 1U;
2532     uint32_t selr;
2533     uint32_t seli;
2534     uint32_t selp;
2535     uint32_t mdec, ndec;
2536 
2537     uint32_t directo = SYSCON_SYSPLLCTRL_DIRECTO(1);
2538 
2539     while (cco_freq < 275000000U)
2540     {
2541         multiply_by <<= 1U; /* double value in each iteration */
2542         pdec <<= 1U;        /* correspondingly double pdec to cancel effect of double msel */
2543         cco_freq = input_freq * multiply_by;
2544     }
2545     selr = 0U;
2546     if (multiply_by < 60U)
2547     {
2548         seli = (multiply_by & 0x3cU) + 4U;
2549         selp = (multiply_by >> 1U) + 1U;
2550     }
2551     else
2552     {
2553         selp = 31U;
2554         if (multiply_by > 16384U)
2555         {
2556             seli = 1U;
2557         }
2558         else if (multiply_by > 8192U)
2559         {
2560             seli = 2U;
2561         }
2562         else if (multiply_by > 2048U)
2563         {
2564             seli = 4U;
2565         }
2566         else if (multiply_by >= 501U)
2567         {
2568             seli = 8U;
2569         }
2570         else
2571         {
2572             seli = 4U * (1024U / (multiply_by + 9U));
2573         }
2574     }
2575 
2576     if (pdec > 1U)
2577     {
2578         directo = 0U;        /* use post divider */
2579         pdec    = pdec / 2U; /* Account for minus 1 encoding */
2580                              /* Translate P value */
2581         switch (pdec)
2582         {
2583             case 1U:
2584                 pdec = 0x62U; /* 1  * 2 */
2585                 break;
2586             case 2U:
2587                 pdec = 0x42U; /* 2  * 2 */
2588                 break;
2589             case 4U:
2590                 pdec = 0x02U; /* 4  * 2 */
2591                 break;
2592             case 8U:
2593                 pdec = 0x0bU; /* 8  * 2 */
2594                 break;
2595             case 16U:
2596                 pdec = 0x11U; /* 16 * 2 */
2597                 break;
2598             case 32U:
2599                 pdec = 0x08U; /* 32 * 2 */
2600                 break;
2601             default:
2602                 pdec = 0x08U;
2603                 break;
2604         }
2605     }
2606 
2607     mdec = PLL_MDEC_VAL_SET(pllEncodeM(multiply_by));
2608     ndec = 0x302U; /* pre divide by 1 (hardcoded) */
2609 
2610     SYSCON->SYSPLLCTRL = directo | (selr << SYSCON_SYSPLLCTRL_SELR_SHIFT) | (seli << SYSCON_SYSPLLCTRL_SELI_SHIFT) |
2611                          (selp << SYSCON_SYSPLLCTRL_SELP_SHIFT);
2612     SYSCON->SYSPLLPDEC = pdec | (1UL << 7U);  /* set Pdec value and assert preq */
2613     SYSCON->SYSPLLNDEC = ndec | (1UL << 10U); /* set Pdec value and assert preq */
2614     SYSCON->SYSPLLMDEC = (1UL << 17U) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */
2615 }
2616 
2617 /* Enable USB DEVICE FULL SPEED clock */
2618 /*! brief Enable USB Device FS clock.
2619  * param	src	: clock source
2620  * param	freq: clock frequency
2621  * Enable USB Device Full Speed clock.
2622  */
CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src,uint32_t freq)2623 bool CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src, uint32_t freq)
2624 {
2625     bool ret = true;
2626 
2627     CLOCK_DisableClock(kCLOCK_Usbd0);
2628 
2629     if (kCLOCK_UsbSrcFro == src)
2630     {
2631         switch (freq)
2632         {
2633             case 96000000U:
2634                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2635                 break;
2636 
2637             case 48000000U:
2638                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
2639                 break;
2640 
2641             default:
2642                 ret = false;
2643                 break;
2644         }
2645         /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
2646         SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
2647                           SYSCON_FROCTRL_USBCLKADJ_MASK;
2648         /* Select FRO 96 or 48 MHz */
2649         CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
2650     }
2651     else
2652     {
2653         /*Set the USB PLL as the Usb0 CLK*/
2654         POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
2655 
2656         usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
2657 
2658         (void)CLOCK_SetUsbPLLFreq(&pll_setup);
2659         CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
2660         CLOCK_AttachClk(kUSB_PLL_to_USB0_CLK);
2661         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2662     }
2663     CLOCK_EnableClock(kCLOCK_Usbd0);
2664     CLOCK_EnableClock(kCLOCK_UsbRam1);
2665 
2666     return ret;
2667 }
2668 
2669 /* Enable USB HOST FULL SPEED clock */
2670 /*! brief Enable USB HOST FS clock.
2671  * param	src	: clock source
2672  * param	freq: clock frequency
2673  * Enable USB HOST Full Speed clock.
2674  */
CLOCK_EnableUsbfs0HostClock(clock_usb_src_t src,uint32_t freq)2675 bool CLOCK_EnableUsbfs0HostClock(clock_usb_src_t src, uint32_t freq)
2676 {
2677     bool ret = true;
2678 
2679     CLOCK_DisableClock(kCLOCK_Usbhmr0);
2680     CLOCK_DisableClock(kCLOCK_Usbhsl0);
2681 
2682     if (kCLOCK_UsbSrcFro == src)
2683     {
2684         switch (freq)
2685         {
2686             case 96000000U:
2687                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2688                 break;
2689 
2690             case 48000000U:
2691                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
2692                 break;
2693 
2694             default:
2695                 ret = false;
2696                 break;
2697         }
2698         /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
2699         SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
2700                           SYSCON_FROCTRL_USBCLKADJ_MASK;
2701         /* Select FRO 96 or 48 MHz */
2702         CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
2703     }
2704     else
2705     {
2706         /*Set the USB PLL as the Usb0 CLK*/
2707         POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
2708 
2709         usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
2710 
2711         (void)CLOCK_SetUsbPLLFreq(&pll_setup);
2712         CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
2713         CLOCK_AttachClk(kUSB_PLL_to_USB0_CLK);
2714         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2715     }
2716     CLOCK_EnableClock(kCLOCK_Usbhmr0);
2717     CLOCK_EnableClock(kCLOCK_Usbhsl0);
2718     CLOCK_EnableClock(kCLOCK_UsbRam1);
2719 
2720     return ret;
2721 }
2722 
2723 /* Enable USB DEVICE HIGH SPEED clock */
2724 /*! brief Enable USB Device HS clock.
2725  * param	src	: clock source
2726  * param	freq: clock frequency
2727  * Enable USB Device High Speed clock.
2728  */
CLOCK_EnableUsbhs0DeviceClock(clock_usb_src_t src,uint32_t freq)2729 bool CLOCK_EnableUsbhs0DeviceClock(clock_usb_src_t src, uint32_t freq)
2730 {
2731     bool ret = true;
2732     CLOCK_DisableClock(kCLOCK_Usbd1);
2733     /* Power on the VD5 for USB PHY */
2734     POWER_SetUsbPhy();
2735     if (kCLOCK_UsbSrcFro == src)
2736     {
2737         switch (freq)
2738         {
2739             case 96000000U:
2740                 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2741                 break;
2742 
2743             case 48000000U:
2744                 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
2745                 break;
2746 
2747             default:
2748                 ret = false;
2749                 break;
2750         }
2751         /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
2752         SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
2753                           SYSCON_FROCTRL_USBCLKADJ_MASK;
2754         /* Select FRO 96 or 48 MHz */
2755         CLOCK_AttachClk(kFRO_HF_to_USB1_CLK);
2756     }
2757     else
2758     {
2759         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2760         usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
2761 
2762         (void)CLOCK_SetUsbPLLFreq(&pll_setup);
2763 
2764         /* Select USB PLL output as USB clock src */
2765         CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false);
2766         CLOCK_AttachClk(kUSB_PLL_to_USB1_CLK);
2767     }
2768 
2769     SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2770     /* Enable USB1D and USB1RAM */
2771     CLOCK_EnableClock(kCLOCK_Usbd1);
2772     CLOCK_EnableClock(kCLOCK_UsbRam1);
2773     POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* Turn on power for USB PHY */
2774     return ret;
2775 }
2776 
2777 /* Enable USB HOST HIGH SPEED clock */
2778 /*! brief Enable USB HOST HS clock.
2779  * param	src	: clock source
2780  * param	freq: clock frequency
2781  * Enable USB HOST High Speed clock.
2782  */
CLOCK_EnableUsbhs0HostClock(clock_usb_src_t src,uint32_t freq)2783 bool CLOCK_EnableUsbhs0HostClock(clock_usb_src_t src, uint32_t freq)
2784 {
2785     bool ret = true;
2786     CLOCK_DisableClock(kCLOCK_Usbh1);
2787     /* Power on the VD5 for USB PHY */
2788     POWER_SetUsbPhy();
2789     if (kCLOCK_UsbSrcFro == src)
2790     {
2791         switch (freq)
2792         {
2793             case 96000000U:
2794                 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2795                 break;
2796 
2797             case 48000000U:
2798                 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
2799                 break;
2800 
2801             default:
2802                 ret = false;
2803                 break;
2804         }
2805         /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
2806         SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
2807                           SYSCON_FROCTRL_USBCLKADJ_MASK;
2808         /* Select FRO 96 or 48 MHz */
2809         CLOCK_AttachClk(kFRO_HF_to_USB1_CLK);
2810     }
2811     else
2812     {
2813         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2814         usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
2815 
2816         (void)CLOCK_SetUsbPLLFreq(&pll_setup);
2817 
2818         /* Select USB PLL output as USB clock src */
2819         CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false);
2820         CLOCK_AttachClk(kUSB_PLL_to_USB1_CLK);
2821     }
2822 
2823     SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2824     /* Enable USBh1 and USB1RAM */
2825     CLOCK_EnableClock(kCLOCK_Usbh1);
2826     CLOCK_EnableClock(kCLOCK_UsbRam1);
2827     POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* Turn on power for USB PHY */
2828     return ret;
2829 }
2830