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 */
CLOCK_GetFRGInputClock(void)870 uint32_t CLOCK_GetFRGInputClock(void)
871 {
872     uint32_t freq = 0U;
873 
874     switch (SYSCON->FRGCLKSEL)
875     {
876         case 0U:
877             freq = CLOCK_GetCoreSysClkFreq();
878             break;
879         case 1U:
880             freq = CLOCK_GetPllOutFreq();
881             break;
882         case 2U:
883             freq = CLOCK_GetFro12MFreq();
884             break;
885         case 3U:
886             freq = CLOCK_GetFroHfFreq();
887             break;
888 
889         default:
890             freq = 0U;
891             break;
892     }
893 
894     return freq;
895 }
896 
897 /* Get FRG Clk */
898 /*! brief  Return Frequency of frg
899  *  return Frequency of FRG
900  */
CLOCK_GetFrgClkFreq(void)901 uint32_t CLOCK_GetFrgClkFreq(void)
902 {
903     uint32_t freq = 0U;
904 
905     if ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_DIV_MASK) == SYSCON_FRGCTRL_DIV_MASK)
906     {
907         freq = (uint32_t)(((uint64_t)CLOCK_GetFRGInputClock() * (SYSCON_FRGCTRL_DIV_MASK + 1U)) /
908                           ((SYSCON_FRGCTRL_DIV_MASK + 1U) +
909                            ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_MULT_MASK) >> SYSCON_FRGCTRL_MULT_SHIFT)));
910     }
911     else
912     {
913         freq = 0U;
914     }
915 
916     return freq;
917 }
918 
919 /* Get DMIC Clk */
920 /*! brief  Return Frequency of dmic
921  *  return Frequency of DMIC
922  */
CLOCK_GetDmicClkFreq(void)923 uint32_t CLOCK_GetDmicClkFreq(void)
924 {
925     uint32_t freq = 0U;
926 
927     switch (SYSCON->DMICCLKSEL)
928     {
929         case 0U:
930             freq = CLOCK_GetFro12MFreq();
931             break;
932         case 1U:
933             freq = CLOCK_GetFroHfFreq();
934             break;
935         case 2U:
936             freq = CLOCK_GetPllOutFreq();
937             break;
938         case 3U:
939             freq = CLOCK_GetI2SMClkFreq();
940             break;
941         case 4U:
942             freq = CLOCK_GetCoreSysClkFreq();
943             break;
944         case 5U:
945             freq = CLOCK_GetWdtOscFreq();
946             break;
947         default:
948             freq = 0U;
949             break;
950     }
951 
952     return freq / ((SYSCON->DMICCLKDIV & 0xffU) + 1U);
953 }
954 
955 /* Set FRG Clk */
CLOCK_SetFRGClock(uint32_t freq)956 uint32_t CLOCK_SetFRGClock(uint32_t freq)
957 {
958     assert(0U != freq);
959 
960     uint32_t input = CLOCK_GetFRGInputClock();
961     uint32_t mul;
962     uint32_t ret;
963 
964     if ((freq > 48000000U) || (freq > input) || (input / freq >= 2U))
965     {
966         /* FRG output frequency should be less than equal to 48MHz */
967         ret = 0U;
968     }
969     else
970     {
971         mul             = (uint32_t)((((uint64_t)input - freq) * 256ULL) / ((uint64_t)freq));
972         SYSCON->FRGCTRL = (mul << SYSCON_FRGCTRL_MULT_SHIFT) | SYSCON_FRGCTRL_DIV_MASK;
973         ret             = 1U;
974     }
975 
976     return ret;
977 }
978 
979 /* Set IP Clk */
980 /*! brief	Return Frequency of selected clock
981  *  return	Frequency of selected clock
982  */
CLOCK_GetFreq(clock_name_t clockName)983 uint32_t CLOCK_GetFreq(clock_name_t clockName)
984 {
985     uint32_t freq;
986     switch (clockName)
987     {
988         case kCLOCK_CoreSysClk:
989             freq = CLOCK_GetCoreSysClkFreq();
990             break;
991         case kCLOCK_BusClk:
992             freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
993             break;
994         case kCLOCK_ClockOut:
995             freq = CLOCK_GetClockOutClkFreq();
996             break;
997         case kCLOCK_Mclk:
998             freq = CLOCK_GetMclkClkFreq();
999             break;
1000         case kCLOCK_FroHf:
1001             freq = CLOCK_GetFroHfFreq();
1002             break;
1003         case kCLOCK_Fro12M:
1004             freq = CLOCK_GetFro12MFreq();
1005             break;
1006         case kCLOCK_ExtClk:
1007             freq = CLOCK_GetExtClkFreq();
1008             break;
1009         case kCLOCK_PllOut:
1010             freq = CLOCK_GetPllOutFreq();
1011             break;
1012         case kCLOCK_WdtOsc:
1013             freq = CLOCK_GetWdtOscFreq();
1014             break;
1015         case kCLOCK_Frg:
1016             freq = CLOCK_GetFrgClkFreq();
1017             break;
1018         case kCLOCK_AsyncApbClk:
1019             freq = CLOCK_GetAsyncApbClkFreq();
1020             break;
1021         case kCLOCK_FlexI2S:
1022             freq = CLOCK_GetI2SMClkFreq();
1023             break;
1024         default:
1025             freq = 0U;
1026             break;
1027     }
1028 
1029     return freq;
1030 }
1031 
1032 /* Set the FLASH wait states for the passed frequency */
1033 /**
1034  * brief	Set the flash wait states for the input freuqency.
1035  * param	iFreq	: Input frequency
1036  * return	Nothing
1037  */
CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)1038 void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq)
1039 {
1040     if (iFreq <= 12000000U)
1041     {
1042         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash1Cycle);
1043     }
1044     else if (iFreq <= 24000000U)
1045     {
1046         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash2Cycle);
1047     }
1048     else if (iFreq <= 36000000U)
1049     {
1050         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash3Cycle);
1051     }
1052     else if (iFreq <= 60000000U)
1053     {
1054         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash4Cycle);
1055     }
1056     else if (iFreq <= 96000000U)
1057     {
1058         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash5Cycle);
1059     }
1060     else if (iFreq <= 120000000U)
1061     {
1062         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash6Cycle);
1063     }
1064     else if (iFreq <= 144000000U)
1065     {
1066         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash7Cycle);
1067     }
1068     else if (iFreq <= 168000000U)
1069     {
1070         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash8Cycle);
1071     }
1072     else
1073     {
1074         CLOCK_SetFLASHAccessCycles(kCLOCK_Flash9Cycle);
1075     }
1076 }
1077 
1078 /* Find encoded NDEC value for raw N value, max N = NVALMAX */
pllEncodeN(uint32_t N)1079 static uint32_t pllEncodeN(uint32_t N)
1080 {
1081     uint32_t x, i;
1082 
1083     /* Find NDec */
1084     switch (N)
1085     {
1086         case 0U:
1087             x = 0x3FFU;
1088             break;
1089 
1090         case 1U:
1091             x = 0x302U;
1092             break;
1093 
1094         case 2U:
1095             x = 0x202U;
1096             break;
1097 
1098         default:
1099             x = 0x080U;
1100             for (i = N; i <= NVALMAX; i++)
1101             {
1102                 x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
1103             }
1104             break;
1105     }
1106 
1107     return x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P);
1108 }
1109 
1110 /* Find decoded N value for raw NDEC value */
pllDecodeN(uint32_t NDEC)1111 static uint32_t pllDecodeN(uint32_t NDEC)
1112 {
1113     uint32_t n, x, i;
1114 
1115     /* Find NDec */
1116     switch (NDEC)
1117     {
1118         case 0x3FFU:
1119             n = 0U;
1120             break;
1121 
1122         case 0x302U:
1123             n = 1U;
1124             break;
1125 
1126         case 0x202U:
1127             n = 2U;
1128             break;
1129 
1130         default:
1131             x = 0x080U;
1132             n = 0xFFFFFFFFU;
1133             for (i = NVALMAX; (i >= 3U); i--)
1134             {
1135                 x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
1136                 if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC)
1137                 {
1138                     /* Decoded value of NDEC */
1139                     n = i;
1140                     break;
1141                 }
1142             }
1143             break;
1144     }
1145 
1146     return n;
1147 }
1148 
1149 /* Find encoded PDEC value for raw P value, max P = PVALMAX */
pllEncodeP(uint32_t P)1150 static uint32_t pllEncodeP(uint32_t P)
1151 {
1152     uint32_t x, i;
1153 
1154     /* Find PDec */
1155     switch (P)
1156     {
1157         case 0U:
1158             x = 0x7FU;
1159             break;
1160 
1161         case 1U:
1162             x = 0x62U;
1163             break;
1164 
1165         case 2U:
1166             x = 0x42U;
1167             break;
1168 
1169         default:
1170             x = 0x10U;
1171             for (i = P; i <= PVALMAX; i++)
1172             {
1173                 x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
1174             }
1175             break;
1176     }
1177 
1178     return x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P);
1179 }
1180 
1181 /* Find decoded P value for raw PDEC value */
pllDecodeP(uint32_t PDEC)1182 static uint32_t pllDecodeP(uint32_t PDEC)
1183 {
1184     uint32_t p, x, i;
1185 
1186     /* Find PDec */
1187     switch (PDEC)
1188     {
1189         case 0x7FU:
1190             p = 0U;
1191             break;
1192 
1193         case 0x62U:
1194             p = 1U;
1195             break;
1196 
1197         case 0x42U:
1198             p = 2U;
1199             break;
1200 
1201         default:
1202             x = 0x10U;
1203             p = 0xFFFFFFFFU;
1204             for (i = PVALMAX; (i >= 3U); i--)
1205             {
1206                 x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
1207                 if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC)
1208                 {
1209                     /* Decoded value of PDEC */
1210                     p = i;
1211                     break;
1212                 }
1213             }
1214             break;
1215     }
1216 
1217     return p;
1218 }
1219 
1220 /* Find encoded MDEC value for raw M value, max M = MVALMAX */
pllEncodeM(uint32_t M)1221 static uint32_t pllEncodeM(uint32_t M)
1222 {
1223     uint32_t i, x;
1224 
1225     /* Find MDec */
1226     switch (M)
1227     {
1228         case 0U:
1229             x = 0x1FFFFU;
1230             break;
1231 
1232         case 1U:
1233             x = 0x18003U;
1234             break;
1235 
1236         case 2U:
1237             x = 0x10003U;
1238             break;
1239 
1240         default:
1241             x = 0x04000U;
1242             for (i = M; i <= MVALMAX; i++)
1243             {
1244                 x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
1245             }
1246             break;
1247     }
1248 
1249     return x & (PLL_MDEC_VAL_M >> PLL_MDEC_VAL_P);
1250 }
1251 
1252 /* Find decoded M value for raw MDEC value */
pllDecodeM(uint32_t MDEC)1253 static uint32_t pllDecodeM(uint32_t MDEC)
1254 {
1255     uint32_t m, i, x;
1256 
1257     /* Find MDec */
1258     switch (MDEC)
1259     {
1260         case 0x1FFFFU:
1261             m = 0U;
1262             break;
1263 
1264         case 0x18003U:
1265             m = 1U;
1266             break;
1267 
1268         case 0x10003U:
1269             m = 2U;
1270             break;
1271 
1272         default:
1273             x = 0x04000U;
1274             m = 0xFFFFFFFFU;
1275             for (i = MVALMAX; (i >= 3U); i--)
1276             {
1277                 x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
1278                 if ((x & (PLL_MDEC_VAL_M >> PLL_MDEC_VAL_P)) == MDEC)
1279                 {
1280                     /* Decoded value of MDEC */
1281                     m = i;
1282                     break;
1283                 }
1284             }
1285             break;
1286     }
1287 
1288     return m;
1289 }
1290 
1291 /* 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)1292 static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
1293 {
1294     /* bandwidth: compute selP from Multiplier */
1295     if (M < 60U)
1296     {
1297         *pSelP = (M >> 1U) + 1U;
1298     }
1299     else
1300     {
1301         *pSelP = PVALMAX - 1U;
1302     }
1303 
1304     /* bandwidth: compute selI from Multiplier */
1305     if (M > 16384U)
1306     {
1307         *pSelI = 1U;
1308     }
1309     else if (M > 8192U)
1310     {
1311         *pSelI = 2U;
1312     }
1313     else if (M > 2048U)
1314     {
1315         *pSelI = 4U;
1316     }
1317     else if (M >= 501U)
1318     {
1319         *pSelI = 8U;
1320     }
1321     else if (M >= 60U)
1322     {
1323         *pSelI = 4U * (1024U / (M + 9U));
1324     }
1325     else
1326     {
1327         *pSelI = (M & 0x3CU) + 4U;
1328     }
1329 
1330     if (*pSelI > ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT))
1331     {
1332         *pSelI = ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT);
1333     }
1334 
1335     *pSelR = 0U;
1336 }
1337 
1338 /* Get predivider (N) from PLL NDEC setting */
findPllPreDiv(uint32_t ctrlReg,uint32_t nDecReg)1339 static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg)
1340 {
1341     uint32_t preDiv = 1;
1342 
1343     /* Direct input is not used? */
1344     if ((ctrlReg & (1UL << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) == 0U)
1345     {
1346         /* Decode NDEC value to get (N) pre divider */
1347         preDiv = pllDecodeN(nDecReg & 0x3FFU);
1348         if (preDiv == 0U)
1349         {
1350             preDiv = 1U;
1351         }
1352     }
1353 
1354     /* Adjusted by 1, directi is used to bypass */
1355     return preDiv;
1356 }
1357 
1358 /* Get postdivider (P) from PLL PDEC setting */
findPllPostDiv(uint32_t ctrlReg,uint32_t pDecReg)1359 static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg)
1360 {
1361     uint32_t postDiv = 1U;
1362 
1363     /* Direct input is not used? */
1364     if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTO_MASK) == 0U)
1365     {
1366         /* Decode PDEC value to get (P) post divider */
1367         postDiv = 2U * pllDecodeP(pDecReg & 0x7FU);
1368         if (postDiv == 0U)
1369         {
1370             postDiv = 2U;
1371         }
1372     }
1373 
1374     /* Adjusted by 1, directo is used to bypass */
1375     return postDiv;
1376 }
1377 
1378 /* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
findPllMMult(uint32_t ctrlReg,uint32_t mDecReg)1379 static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg)
1380 {
1381     uint32_t mMult = 1U;
1382 
1383     /* Decode MDEC value to get (M) multiplier */
1384     mMult = pllDecodeM(mDecReg & 0x1FFFFU);
1385 
1386     if (mMult == 0U)
1387     {
1388         mMult = 1U;
1389     }
1390 
1391     return mMult;
1392 }
1393 
1394 /* Convert the binary to fractional part */
Binary2Fractional(uint32_t binaryPart)1395 static double Binary2Fractional(uint32_t binaryPart)
1396 {
1397     double fractional = 0.0;
1398     for (uint32_t i = 0U; i <= 14U; i++)
1399     {
1400         fractional += (double)(uint32_t)((binaryPart >> i) & 0x1UL) / (double)(uint32_t)(1UL << (15U - i));
1401     }
1402     return fractional;
1403 }
1404 
1405 /* Find greatest common divisor between m and n */
FindGreatestCommonDivisor(uint32_t m,uint32_t n)1406 static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
1407 {
1408     uint32_t tmp;
1409 
1410     while (n != 0U)
1411     {
1412         tmp = n;
1413         n   = m % n;
1414         m   = tmp;
1415     }
1416 
1417     return m;
1418 }
1419 
1420 /*
1421  * Set PLL output based on desired output rate.
1422  * In this function, the it calculates the PLL setting for output frequency from input clock
1423  * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
1424  * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
1425  */
CLOCK_GetPllConfigInternal(uint32_t finHz,uint32_t foutHz,pll_setup_t * pSetup)1426 static pll_error_t CLOCK_GetPllConfigInternal(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup)
1427 {
1428     uint32_t nDivOutHz, fccoHz, multFccoDiv;
1429     uint32_t pllPreDivider, pllMultiplier, pllPostDivider;
1430     uint32_t pllDirectInput, pllDirectOutput;
1431     uint32_t pllSelP, pllSelI, pllSelR, uplimoff;
1432 
1433     /* Baseline parameters (no input or output dividers) */
1434     pllPreDivider   = 1U; /* 1 implies pre-divider will be disabled */
1435     pllPostDivider  = 0U; /* 0 implies post-divider will be disabled */
1436     pllDirectOutput = 1U;
1437     multFccoDiv     = 2U;
1438 
1439     /* Verify output rate parameter */
1440     if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
1441     {
1442         /* Maximum PLL output with post divider=1 cannot go above this frequency */
1443         return kStatus_PLL_OutputTooHigh;
1444     }
1445     if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
1446     {
1447         /* Minmum PLL output with maximum post divider cannot go below this frequency */
1448         return kStatus_PLL_OutputTooLow;
1449     }
1450 
1451     /* Verify input rate parameter */
1452     if (finHz < PLL_LOWER_IN_LIMIT)
1453     {
1454         /* Input clock into the PLL cannot be lower than this */
1455         return kStatus_PLL_InputTooLow;
1456     }
1457 
1458     /* Find the optimal CCO frequency for the output and input that
1459        will keep it inside the PLL CCO range. This may require
1460        tweaking the post-divider for the PLL. */
1461     fccoHz = foutHz;
1462     while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
1463     {
1464         /* CCO output is less than minimum CCO range, so the CCO output
1465            needs to be bumped up and the post-divider is used to bring
1466            the PLL output back down. */
1467         pllPostDivider++;
1468         if (pllPostDivider > PVALMAX)
1469         {
1470             return kStatus_PLL_OutsideIntLimit;
1471         }
1472 
1473         /* Target CCO goes up, PLL output goes down */
1474         fccoHz          = foutHz * (pllPostDivider * 2U);
1475         pllDirectOutput = 0U;
1476     }
1477 
1478     /* Determine if a pre-divider is needed to get the best frequency */
1479     if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz))
1480     {
1481         uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz));
1482 
1483         if (a > 20000U)
1484         {
1485             a = (multFccoDiv * finHz) / a;
1486             if ((a != 0U) && (a < PLL_MAX_N_DIV))
1487             {
1488                 pllPreDivider = a;
1489             }
1490         }
1491     }
1492 
1493     /* Bypass pre-divider hardware if pre-divider is 1 */
1494     if (pllPreDivider > 1U)
1495     {
1496         pllDirectInput = 0U;
1497     }
1498     else
1499     {
1500         pllDirectInput = 1U;
1501     }
1502 
1503     /* Determine PLL multipler */
1504     nDivOutHz     = (finHz / pllPreDivider);
1505     pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv;
1506 
1507     /* Find optimal values for filter */
1508     /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
1509     if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
1510     {
1511         pllMultiplier++;
1512     }
1513 
1514     /* Setup filtering */
1515     pllFindSel(pllMultiplier, &pllSelP, &pllSelI, &pllSelR);
1516     uplimoff = 0U;
1517 
1518     /* Get encoded value for M (mult) and use manual filter, disable SS mode */
1519     pSetup->pllmdec = PLL_MDEC_VAL_SET(pllEncodeM(pllMultiplier));
1520 
1521     /* Get encoded values for N (prediv) and P (postdiv) */
1522     pSetup->pllndec = PLL_NDEC_VAL_SET(pllEncodeN(pllPreDivider));
1523     pSetup->pllpdec = PLL_PDEC_VAL_SET(pllEncodeP(pllPostDivider));
1524 
1525     /* PLL control */
1526     pSetup->pllctrl = (pllSelR << SYSCON_SYSPLLCTRL_SELR_SHIFT) |           /* Filter coefficient */
1527                       (pllSelI << SYSCON_SYSPLLCTRL_SELI_SHIFT) |           /* Filter coefficient */
1528                       (pllSelP << SYSCON_SYSPLLCTRL_SELP_SHIFT) |           /* Filter coefficient */
1529                       (0UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT) |             /* PLL bypass mode disabled */
1530                       (uplimoff << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT) |      /* SS/fractional mode disabled */
1531                       (pllDirectInput << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT) | /* Bypass pre-divider? */
1532                       (pllDirectOutput << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT); /* Bypass post-divider? */
1533 
1534     return kStatus_PLL_Success;
1535 }
1536 
1537 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1538 /* Alloct the static buffer for cache. */
1539 static pll_setup_t s_PllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
1540 static uint32_t s_FinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT]  = {0};
1541 static uint32_t s_FoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
1542 static uint32_t s_PllSetupCacheIdx                                  = 0U;
1543 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1544 
1545 /*
1546  * Calculate the PLL setting values from input clock freq to output freq.
1547  */
CLOCK_GetPllConfig(uint32_t finHz,uint32_t foutHz,pll_setup_t * pSetup)1548 static pll_error_t CLOCK_GetPllConfig(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup)
1549 {
1550     pll_error_t retErr;
1551 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1552     uint32_t i;
1553 
1554     for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
1555     {
1556         if ((finHz == s_FinHzCache[i]) && (foutHz == s_FoutHzCache[i]))
1557         {
1558             /* Hit the target in cache buffer. */
1559             pSetup->pllctrl = s_PllSetupCacheStruct[i].pllctrl;
1560             pSetup->pllndec = s_PllSetupCacheStruct[i].pllndec;
1561             pSetup->pllpdec = s_PllSetupCacheStruct[i].pllpdec;
1562             pSetup->pllmdec = s_PllSetupCacheStruct[i].pllmdec;
1563             retErr          = kStatus_PLL_Success;
1564             break;
1565         }
1566     }
1567 
1568     if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1569     {
1570         return retErr;
1571     }
1572 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1573 
1574     /* No cache or did not hit the cache. */
1575     retErr = CLOCK_GetPllConfigInternal(finHz, foutHz, pSetup);
1576 
1577 #if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
1578     if (kStatus_PLL_Success == retErr)
1579     {
1580         /* Cache the most recent calulation result into buffer. */
1581         s_FinHzCache[s_PllSetupCacheIdx]  = finHz;
1582         s_FoutHzCache[s_PllSetupCacheIdx] = foutHz;
1583 
1584         s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllctrl = pSetup->pllctrl;
1585         s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllndec = pSetup->pllndec;
1586         s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllpdec = pSetup->pllpdec;
1587         s_PllSetupCacheStruct[s_PllSetupCacheIdx].pllmdec = pSetup->pllmdec;
1588         /* Update the index for next available buffer. */
1589         s_PllSetupCacheIdx = (s_PllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
1590     }
1591 #endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
1592 
1593     return retErr;
1594 }
1595 
1596 /* Update SYSTEM PLL rate variable */
CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t * pSetup)1597 static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup)
1598 {
1599     s_Pll_Freq = CLOCK_GetSystemPLLOutFromSetup(pSetup);
1600 }
1601 
1602 /* Update AUDIO PLL rate variable */
CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t * pSetup)1603 static void CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t *pSetup)
1604 {
1605     s_Audio_Pll_Freq = CLOCK_GetAudioPLLOutFromSetup(pSetup);
1606 }
1607 
1608 /* Update AUDIO Fractional PLL rate variable */
CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pll_setup_t * pSetup)1609 static void CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pll_setup_t *pSetup)
1610 {
1611     s_Audio_Pll_Freq = CLOCK_GetAudioPLLOutFromFractSetup(pSetup);
1612 }
1613 
1614 /* Update USB PLL rate variable */
CLOCK_GetUsbPLLOutFromSetupUpdate(const usb_pll_setup_t * pSetup)1615 static void CLOCK_GetUsbPLLOutFromSetupUpdate(const usb_pll_setup_t *pSetup)
1616 {
1617     s_Usb_Pll_Freq = CLOCK_GetUsbPLLOutFromSetup(pSetup);
1618 }
1619 
1620 /* Return System PLL input clock rate */
1621 /*! brief	Return System PLL input clock rate
1622  *  return	System PLL input clock rate
1623  */
CLOCK_GetSystemPLLInClockRate(void)1624 uint32_t CLOCK_GetSystemPLLInClockRate(void)
1625 {
1626     uint32_t clkRate = 0U;
1627 
1628     switch ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK))
1629     {
1630         case 0x00U:
1631             clkRate = CLK_FRO_12MHZ;
1632             break;
1633 
1634         case 0x01U:
1635             clkRate = CLOCK_GetExtClkFreq();
1636             break;
1637 
1638         case 0x02U:
1639             clkRate = CLOCK_GetWdtOscFreq();
1640             break;
1641 
1642         case 0x03U:
1643             clkRate = CLOCK_GetOsc32KFreq();
1644             break;
1645 
1646         default:
1647             clkRate = 0U;
1648             break;
1649     }
1650 
1651     return clkRate;
1652 }
1653 
1654 /* Return Audio PLL input clock rate */
1655 /*! brief	Return Audio PLL input clock rate
1656  *  return	Audio PLL input clock rate
1657  */
CLOCK_GetAudioPLLInClockRate(void)1658 uint32_t CLOCK_GetAudioPLLInClockRate(void)
1659 {
1660     uint32_t clkRate = 0U;
1661 
1662     switch ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK))
1663     {
1664         case 0x00U:
1665             clkRate = CLK_FRO_12MHZ;
1666             break;
1667 
1668         case 0x01U:
1669             clkRate = CLOCK_GetExtClkFreq();
1670             break;
1671 
1672         default:
1673             clkRate = 0U;
1674             break;
1675     }
1676 
1677     return clkRate;
1678 }
1679 
1680 /* Return System PLL output clock rate from setup structure */
1681 /*! brief	Return System PLL output clock rate from setup structure
1682  *  param	pSetup	: Pointer to a PLL setup structure
1683  *  return	System PLL output clock rate the setup structure will generate
1684  */
CLOCK_GetSystemPLLOutFromSetup(pll_setup_t * pSetup)1685 uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup)
1686 {
1687     uint32_t prediv, postdiv, mMult, inPllRate;
1688     uint64_t workRate;
1689 
1690     inPllRate = CLOCK_GetSystemPLLInClockRate();
1691     /* If the PLL is bypassed, PLL would not be used and the output of PLL module would just be the input clock*/
1692     if ((pSetup->pllctrl & (SYSCON_SYSPLLCTRL_BYPASS_MASK)) == 0U)
1693     {
1694         /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
1695         /*
1696          * 1. Pre-divider
1697          * Pre-divider is only available when the DIRECTI is disabled.
1698          */
1699         if (0U == (pSetup->pllctrl & SYSCON_SYSPLLCTRL_DIRECTI_MASK))
1700         {
1701             prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
1702         }
1703         else
1704         {
1705             prediv = 1U; /* The pre-divider is bypassed. */
1706         }
1707         /*
1708          * 2. Post-divider
1709          * Post-divider is only available when the DIRECTO is disabled.
1710          */
1711         if (0U == (pSetup->pllctrl & SYSCON_SYSPLLCTRL_DIRECTO_MASK))
1712         {
1713             postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
1714         }
1715         else
1716         {
1717             postdiv = 1U; /* The post-divider is bypassed. */
1718         }
1719         /* Adjust input clock */
1720         inPllRate = inPllRate / prediv;
1721 
1722         /* MDEC used for rate */
1723         mMult    = findPllMMult(pSetup->pllctrl, pSetup->pllmdec);
1724         workRate = (uint64_t)inPllRate * (uint64_t)mMult;
1725 
1726         workRate = workRate / ((uint64_t)postdiv);
1727         workRate = workRate * 2U; /* SYS PLL hardware cco is divided by 2 before the M-DIVIDER*/
1728     }
1729     else
1730     {
1731         /* In bypass mode */
1732         workRate = (uint64_t)inPllRate;
1733     }
1734 
1735     return (uint32_t)workRate;
1736 }
1737 
1738 /* Return Usb PLL output clock rate from setup structure */
1739 /*! brief	Return System USB PLL output clock rate from setup structure
1740  *  param	pSetup	: Pointer to a PLL setup structure
1741  *  return	System PLL output clock rate the setup structure will generate
1742  */
CLOCK_GetUsbPLLOutFromSetup(const usb_pll_setup_t * pSetup)1743 uint32_t CLOCK_GetUsbPLLOutFromSetup(const usb_pll_setup_t *pSetup)
1744 {
1745     uint32_t nsel, psel, msel, inPllRate;
1746     uint64_t workRate;
1747     inPllRate = CLOCK_GetExtClkFreq();
1748     msel      = pSetup->msel;
1749     psel      = pSetup->psel;
1750     nsel      = pSetup->nsel;
1751 
1752     if (pSetup->fbsel)
1753     {
1754         /*integer_mode: Fout = M*(Fin/N),  Fcco = 2*P*M*(Fin/N) */
1755         workRate = (uint64_t)(inPllRate) * (msel + 1ULL) / (nsel + 1ULL);
1756     }
1757     else
1758     {
1759         /* non integer_mode: Fout = M*(Fin/N)/(2*P), Fcco = M * (Fin/N) */
1760         workRate = ((uint64_t)inPllRate / (nsel + 1ULL)) * (msel + 1ULL) / (2U * (1UL << (psel & 3U)));
1761     }
1762 
1763     return (uint32_t)workRate;
1764 }
1765 
1766 /* Return Audio PLL output clock rate from setup structure */
1767 /*! brief	Return System AUDIO PLL output clock rate from setup structure
1768  *  param	pSetup	: Pointer to a PLL setup structure
1769  *  return	System PLL output clock rate the setup structure will generate
1770  */
CLOCK_GetAudioPLLOutFromSetup(pll_setup_t * pSetup)1771 uint32_t CLOCK_GetAudioPLLOutFromSetup(pll_setup_t *pSetup)
1772 {
1773     uint32_t prediv, postdiv, mMult, inPllRate;
1774     uint64_t workRate;
1775 
1776     inPllRate = CLOCK_GetAudioPLLInClockRate();
1777     if ((pSetup->pllctrl & (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) == 0U)
1778     {
1779         /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
1780         /*
1781          * 1. Pre-divider
1782          * Pre-divider is only available when the DIRECTI is disabled.
1783          */
1784         if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTI_MASK))
1785         {
1786             prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
1787         }
1788         else
1789         {
1790             prediv = 1U; /* The pre-divider is bypassed. */
1791         }
1792         /*
1793          * 2. Post-divider
1794          * Post-divider is only available when the DIRECTO is disabled.
1795          */
1796         if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTO_MASK))
1797         {
1798             postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
1799         }
1800         else
1801         {
1802             postdiv = 1U; /* The post-divider is bypassed. */
1803         }
1804         /* Adjust input clock */
1805         inPllRate = inPllRate / prediv;
1806 
1807         /* MDEC used for rate */
1808         mMult    = findPllMMult(pSetup->pllctrl, pSetup->pllmdec);
1809         workRate = (uint64_t)inPllRate * (uint64_t)mMult;
1810 
1811         workRate = workRate / ((uint64_t)postdiv);
1812         workRate = workRate * 2U; /* SYS PLL hardware cco is divided by 2 before the M-DIVIDER*/
1813     }
1814     else
1815     {
1816         /* In bypass mode */
1817         workRate = (uint64_t)inPllRate;
1818     }
1819 
1820     return (uint32_t)workRate;
1821 }
1822 
1823 /* Return Audio PLL output clock rate from audio fractioanl setup structure */
1824 /*! brief	Return System AUDIO PLL output clock rate from audio fractioanl setup structure
1825  *  param	pSetup	: Pointer to a PLL setup structure
1826  *  return	System PLL output clock rate the setup structure will generate
1827  */
CLOCK_GetAudioPLLOutFromFractSetup(pll_setup_t * pSetup)1828 uint32_t CLOCK_GetAudioPLLOutFromFractSetup(pll_setup_t *pSetup)
1829 {
1830     uint32_t prediv, postdiv, inPllRate;
1831     double workRate, mMultFactional;
1832 
1833     inPllRate = CLOCK_GetAudioPLLInClockRate();
1834     if ((pSetup->pllctrl & (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) == 0U)
1835     {
1836         /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
1837         /*
1838          * 1. Pre-divider
1839          * Pre-divider is only available when the DIRECTI is disabled.
1840          */
1841         if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTI_MASK))
1842         {
1843             prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
1844         }
1845         else
1846         {
1847             prediv = 1U; /* The pre-divider is bypassed. */
1848         }
1849         /*
1850          * 2. Post-divider
1851          * Post-divider is only available when the DIRECTO is disabled.
1852          */
1853         if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTO_MASK))
1854         {
1855             postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
1856         }
1857         else
1858         {
1859             postdiv = 1U; /* The post-divider is bypassed. */
1860         }
1861         /* Adjust input clock */
1862         inPllRate = inPllRate / prediv;
1863 
1864         mMultFactional =
1865             (double)(uint32_t)(pSetup->audpllfrac >> 15U) + (double)Binary2Fractional(pSetup->audpllfrac & 0x7FFFU);
1866         workRate = (double)inPllRate * (double)mMultFactional;
1867 
1868         workRate = workRate / ((double)postdiv);
1869         workRate = workRate * 2.0; /* SYS PLL hardware cco is divided by 2 before the M-DIVIDER*/
1870     }
1871     else
1872     {
1873         /* In bypass mode */
1874         workRate = (double)inPllRate;
1875     }
1876 
1877     return (uint32_t)workRate;
1878 }
1879 
1880 /* Set the current PLL Rate */
1881 /*! brief Store the current PLL rate
1882  *  param	rate: Current rate of the PLL
1883  *  return	Nothing
1884  **/
CLOCK_SetStoredPLLClockRate(uint32_t rate)1885 void CLOCK_SetStoredPLLClockRate(uint32_t rate)
1886 {
1887     s_Pll_Freq = rate;
1888 }
1889 
1890 /* Set the current Audio PLL Rate */
1891 /*! brief Store the current AUDIO PLL rate
1892  *  param	rate: Current rate of the PLL
1893  *  return	Nothing
1894  **/
CLOCK_SetStoredAudioPLLClockRate(uint32_t rate)1895 void CLOCK_SetStoredAudioPLLClockRate(uint32_t rate)
1896 {
1897     s_Audio_Pll_Freq = rate;
1898 }
1899 
1900 /* Set the current Usb PLL Rate */
CLOCK_SetStoredUsbPLLClockRate(uint32_t rate)1901 void CLOCK_SetStoredUsbPLLClockRate(uint32_t rate)
1902 {
1903     s_Usb_Pll_Freq = rate;
1904 }
1905 
1906 /* Return System PLL output clock rate */
1907 /*! brief	Return System PLL output clock rate
1908  *  param	recompute	: Forces a PLL rate recomputation if true
1909  *  return	System PLL output clock rate
1910  *  note	The PLL rate is cached in the driver in a variable as
1911  *  the rate computation function can take some time to perform. It
1912  *  is recommended to use 'false' with the 'recompute' parameter.
1913  */
CLOCK_GetSystemPLLOutClockRate(bool recompute)1914 uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute)
1915 {
1916     pll_setup_t Setup;
1917     uint32_t rate;
1918 
1919     if ((recompute) || (s_Pll_Freq == 0U))
1920     {
1921         Setup.pllctrl = SYSCON->SYSPLLCTRL;
1922         Setup.pllndec = SYSCON->SYSPLLNDEC;
1923         Setup.pllpdec = SYSCON->SYSPLLPDEC;
1924         Setup.pllmdec = SYSCON->SYSPLLMDEC;
1925 
1926         CLOCK_GetSystemPLLOutFromSetupUpdate(&Setup);
1927     }
1928 
1929     rate = s_Pll_Freq;
1930 
1931     return rate;
1932 }
1933 
1934 /* Return AUDIO PLL output clock rate */
1935 /*! brief	Return System AUDIO PLL output clock rate
1936  *  param	recompute	: Forces a AUDIO PLL rate recomputation if true
1937  *  return	System AUDIO PLL output clock rate
1938  *  note	The AUDIO PLL rate is cached in the driver in a variable as
1939  *  the rate computation function can take some time to perform. It
1940  *  is recommended to use 'false' with the 'recompute' parameter.
1941  */
CLOCK_GetAudioPLLOutClockRate(bool recompute)1942 uint32_t CLOCK_GetAudioPLLOutClockRate(bool recompute)
1943 {
1944     pll_setup_t Setup;
1945     uint32_t rate;
1946 
1947     if ((recompute) || (s_Audio_Pll_Freq == 0U))
1948     {
1949         Setup.pllctrl = SYSCON->AUDPLLCTRL;
1950         Setup.pllndec = SYSCON->AUDPLLNDEC;
1951         Setup.pllpdec = SYSCON->AUDPLLPDEC;
1952         Setup.pllmdec = SYSCON->AUDPLLMDEC;
1953 
1954         CLOCK_GetAudioPLLOutFromSetupUpdate(&Setup);
1955     }
1956 
1957     rate = s_Audio_Pll_Freq;
1958     return rate;
1959 }
1960 
1961 /* Return USB PLL output clock rate */
CLOCK_GetUsbPLLOutClockRate(bool recompute)1962 uint32_t CLOCK_GetUsbPLLOutClockRate(bool recompute)
1963 {
1964     usb_pll_setup_t Setup;
1965     uint32_t rate;
1966 
1967     if ((recompute) || (s_Usb_Pll_Freq == 0U))
1968     {
1969         Setup.msel  = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_MSEL_SHIFT) & SYSCON_USBPLLCTRL_MSEL_MASK);
1970         Setup.psel  = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_PSEL_SHIFT) & SYSCON_USBPLLCTRL_PSEL_MASK);
1971         Setup.nsel  = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_NSEL_SHIFT) & SYSCON_USBPLLCTRL_NSEL_MASK);
1972         Setup.fbsel = (0UL != ((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_FBSEL_SHIFT) & SYSCON_USBPLLCTRL_FBSEL_MASK));
1973         Setup.bypass =
1974             (0UL != ((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_BYPASS_SHIFT) & SYSCON_USBPLLCTRL_BYPASS_MASK));
1975         Setup.direct =
1976             (0UL != ((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_DIRECT_SHIFT) & SYSCON_USBPLLCTRL_DIRECT_MASK));
1977         CLOCK_GetUsbPLLOutFromSetupUpdate(&Setup);
1978     }
1979 
1980     rate = s_Usb_Pll_Freq;
1981     return rate;
1982 }
1983 
1984 /* Set PLL output based on the passed PLL setup data */
1985 /*! brief	Set PLL output based on the passed PLL setup data
1986  *  param	pControl	: Pointer to populated PLL control structure to generate setup with
1987  *  param	pSetup		: Pointer to PLL setup structure to be filled
1988  *  return	PLL_ERROR_SUCCESS on success, or PLL setup error code
1989  *  note	Actual frequency for setup may vary from the desired frequency based on the
1990  *  accuracy of input clocks, rounding, non-fractional PLL mode, etc.
1991  */
CLOCK_SetupPLLData(pll_config_t * pControl,pll_setup_t * pSetup)1992 pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
1993 {
1994     uint32_t inRate;
1995     pll_error_t pllError;
1996 
1997     /* Determine input rate for the PLL */
1998     if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
1999     {
2000         inRate = pControl->inputRate;
2001     }
2002     else
2003     {
2004         inRate = CLOCK_GetSystemPLLInClockRate();
2005     }
2006 
2007     /* PLL flag options */
2008     pllError        = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup);
2009     pSetup->pllRate = pControl->desiredRate;
2010     return pllError;
2011 }
2012 
2013 /* Set PLL output from PLL setup structure */
2014 /*! brief	Set PLL output from PLL setup structure (precise frequency)
2015  * param	pSetup	: Pointer to populated PLL setup structure
2016  * param flagcfg : Flag configuration for PLL config structure
2017  * return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2018  * note	This function will power off the PLL, setup the PLL with the
2019  * new setup data, and then optionally powerup the PLL, wait for PLL lock,
2020  * and adjust system voltages to the new PLL rate. The function will not
2021  * alter any source clocks (ie, main systen clock) that may use the PLL,
2022  * so these should be setup prior to and after exiting the function.
2023  */
CLOCK_SetupSystemPLLPrec(pll_setup_t * pSetup,uint32_t flagcfg)2024 pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
2025 {
2026     if ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) == 0x01U)
2027     {
2028         /* Turn on the ext clock if system pll input select clk_in */
2029         CLOCK_Enable_SysOsc(true);
2030     }
2031     /* Enable power for PLLs */
2032     POWER_SetPLL();
2033     /* Power off PLL during setup changes */
2034     POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
2035     /*!< Set FLASH waitstates for core */
2036     CLOCK_SetFLASHAccessCyclesForFreq(pSetup->pllRate);
2037     pSetup->flags = flagcfg;
2038 
2039     /* Write PLL setup data */
2040     SYSCON->SYSPLLCTRL = pSetup->pllctrl;
2041     SYSCON->SYSPLLNDEC = pSetup->pllndec;
2042     SYSCON->SYSPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
2043     SYSCON->SYSPLLPDEC = pSetup->pllpdec;
2044     SYSCON->SYSPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
2045     SYSCON->SYSPLLMDEC = pSetup->pllmdec;
2046     SYSCON->SYSPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
2047 
2048     /* Flags for lock or power on */
2049     if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
2050     {
2051         /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
2052         uint32_t maxCCO    = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
2053         uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
2054 
2055         /* Initialize  and power up PLL */
2056         SYSCON->SYSPLLMDEC = maxCCO;
2057         POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
2058 
2059         /* Set mreq to activate */
2060         SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
2061 
2062         /* Delay for 72 uSec @ 12Mhz */
2063         SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2064 
2065         /* clear mreq to prepare for restoring mreq */
2066         SYSCON->SYSPLLMDEC = curSSCTRL;
2067 
2068         /* set original value back and activate */
2069         SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
2070 
2071         /* Enable peripheral states by setting low */
2072         POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
2073     }
2074     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2075     {
2076         while (CLOCK_IsSystemPLLLocked() == false)
2077         {
2078         }
2079     }
2080 
2081     /* Update current programmed PLL rate var */
2082     CLOCK_GetSystemPLLOutFromSetupUpdate(pSetup);
2083 
2084     /* System voltage adjustment, occurs prior to setting main system clock */
2085     if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0U)
2086     {
2087         POWER_SetVoltageForFreq(s_Pll_Freq);
2088     }
2089 
2090     return kStatus_PLL_Success;
2091 }
2092 
2093 /* Set AUDIO PLL output from AUDIO PLL setup structure */
2094 /*! brief	Set AUDIO PLL output from AUDIOPLL setup structure (precise frequency)
2095  * param	pSetup	: Pointer to populated PLL setup structure
2096  * param flagcfg : Flag configuration for PLL config structure
2097  * return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2098  * note	This function will power off the PLL, setup the PLL with the
2099  * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
2100  * and adjust system voltages to the new AUDIOPLL rate. The function will not
2101  * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
2102  * so these should be setup prior to and after exiting the function.
2103  */
CLOCK_SetupAudioPLLPrec(pll_setup_t * pSetup,uint32_t flagcfg)2104 pll_error_t CLOCK_SetupAudioPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
2105 {
2106     if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
2107     {
2108         /* Turn on the ext clock if system pll input select clk_in */
2109         CLOCK_Enable_SysOsc(true);
2110     }
2111     /* Enable power VD3 for PLLs */
2112     POWER_SetPLL();
2113     /* Power off PLL during setup changes */
2114     POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
2115 
2116     pSetup->flags = flagcfg;
2117 
2118     /* Write PLL setup data */
2119     SYSCON->AUDPLLCTRL = pSetup->pllctrl;
2120     SYSCON->AUDPLLNDEC = pSetup->pllndec;
2121     SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
2122     SYSCON->AUDPLLPDEC = pSetup->pllpdec;
2123     SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
2124     SYSCON->AUDPLLMDEC = pSetup->pllmdec;
2125     SYSCON->AUDPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
2126     SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(1);                            /* disable fractional function */
2127 
2128     /* Flags for lock or power on */
2129     if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
2130     {
2131         /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
2132         uint32_t maxCCO    = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
2133         uint32_t curSSCTRL = SYSCON->AUDPLLMDEC & ~(1UL << 17U);
2134 
2135         /* Initialize  and power up PLL */
2136         SYSCON->AUDPLLMDEC = maxCCO;
2137         POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2138 
2139         /* Set mreq to activate */
2140         SYSCON->AUDPLLMDEC = maxCCO | (1UL << 17U);
2141 
2142         /* Delay for 72 uSec @ 12Mhz */
2143         SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2144 
2145         /* clear mreq to prepare for restoring mreq */
2146         SYSCON->AUDPLLMDEC = curSSCTRL;
2147 
2148         /* set original value back and activate */
2149         SYSCON->AUDPLLMDEC = curSSCTRL | (1UL << 17U);
2150 
2151         /* Enable peripheral states by setting low */
2152         POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2153     }
2154     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2155     {
2156         while (CLOCK_IsAudioPLLLocked() == false)
2157         {
2158         }
2159     }
2160 
2161     /* Update current programmed PLL rate var */
2162     CLOCK_GetAudioPLLOutFromSetupUpdate(pSetup);
2163 
2164     return kStatus_PLL_Success;
2165 }
2166 
2167 /* Set AUDIO PLL output from AUDIO PLL fractional setup structure */
2168 /*! brief	Set AUDIO PLL output from AUDIOPLL setup structure using the Audio Fractional divider register(precise
2169  * frequency)
2170  * param	pSetup	: Pointer to populated PLL setup structure
2171  * param flagcfg : Flag configuration for PLL config structure
2172  * return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2173  * note	This function will power off the PLL, setup the PLL with the
2174  * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
2175  * and adjust system voltages to the new AUDIOPLL rate. The function will not
2176  * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
2177  * so these should be setup prior to and after exiting the function.
2178  */
CLOCK_SetupAudioPLLPrecFract(pll_setup_t * pSetup,uint32_t flagcfg)2179 pll_error_t CLOCK_SetupAudioPLLPrecFract(pll_setup_t *pSetup, uint32_t flagcfg)
2180 {
2181     if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
2182     {
2183         /* Turn on the ext clock if system pll input select clk_in */
2184         CLOCK_Enable_SysOsc(true);
2185     }
2186     /* Enable power VD3 for PLLs */
2187     POWER_SetPLL();
2188     /* Power off PLL during setup changes */
2189     POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
2190 
2191     pSetup->flags = flagcfg;
2192 
2193     /* Write PLL setup data */
2194     SYSCON->AUDPLLCTRL = pSetup->pllctrl;
2195     SYSCON->AUDPLLNDEC = pSetup->pllndec;
2196     SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
2197     SYSCON->AUDPLLPDEC = pSetup->pllpdec;
2198     SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
2199     SYSCON->AUDPLLMDEC = pSetup->pllmdec;
2200     SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(0); /* enable fractional function */
2201     SYSCON->AUDPLLFRAC = pSetup->audpllfrac;
2202     SYSCON->AUDPLLFRAC = pSetup->audpllfrac | (1UL << SYSCON_AUDPLLFRAC_REQ_SHIFT);
2203 
2204     /* Enable peripheral states by setting low */
2205     POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2206 
2207     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2208     {
2209         while (CLOCK_IsAudioPLLLocked() == false)
2210         {
2211         }
2212     }
2213 
2214     /* Update current programmed PLL rate var */
2215     CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pSetup);
2216 
2217     return kStatus_PLL_Success;
2218 }
2219 
2220 /* Set Audio PLL output based on the passed Audio PLL setup data */
2221 /*! brief	Set AUDIO PLL output based on the passed AUDIO PLL setup data
2222  *  param	pControl	: Pointer to populated PLL control structure to generate setup with
2223  *  param	pSetup		: Pointer to PLL setup structure to be filled
2224  *  return	PLL_ERROR_SUCCESS on success, or PLL setup error code
2225  *  note	Actual frequency for setup may vary from the desired frequency based on the
2226  *  accuracy of input clocks, rounding, non-fractional PLL mode, etc.
2227  */
CLOCK_SetupAudioPLLData(pll_config_t * pControl,pll_setup_t * pSetup)2228 pll_error_t CLOCK_SetupAudioPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
2229 {
2230     uint32_t inRate;
2231     pll_error_t pllError;
2232 
2233     /* Determine input rate for the PLL */
2234     if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
2235     {
2236         inRate = pControl->inputRate;
2237     }
2238     else
2239     {
2240         inRate = CLOCK_GetAudioPLLInClockRate();
2241     }
2242 
2243     /* PLL flag options */
2244     pllError        = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup);
2245     pSetup->pllRate = pControl->desiredRate;
2246     return pllError;
2247 }
2248 
2249 /* Setup PLL Frequency from pre-calculated value */
2250 /**
2251  * brief	Set PLL output from PLL setup structure (precise frequency)
2252  * param	pSetup	: Pointer to populated PLL setup structure
2253  * return	kStatus_PLL_Success on success, or PLL setup error code
2254  * note	This function will power off the PLL, setup the PLL with the
2255  * new setup data, and then optionally powerup the PLL, wait for PLL lock,
2256  * and adjust system voltages to the new PLL rate. The function will not
2257  * alter any source clocks (ie, main systen clock) that may use the PLL,
2258  * so these should be setup prior to and after exiting the function.
2259  */
CLOCK_SetPLLFreq(const pll_setup_t * pSetup)2260 pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup)
2261 {
2262     if ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) == 0x01U)
2263     {
2264         /* Turn on the ext clock if system pll input select clk_in */
2265         CLOCK_Enable_SysOsc(true);
2266     }
2267     /* Enable power VD3 for PLLs */
2268     POWER_SetPLL();
2269     /* Power off PLL during setup changes */
2270     POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
2271 
2272     /* Write PLL setup data */
2273     SYSCON->SYSPLLCTRL = pSetup->pllctrl;
2274     SYSCON->SYSPLLNDEC = pSetup->pllndec;
2275     SYSCON->SYSPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
2276     SYSCON->SYSPLLPDEC = pSetup->pllpdec;
2277     SYSCON->SYSPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
2278     SYSCON->SYSPLLMDEC = pSetup->pllmdec;
2279     SYSCON->SYSPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
2280 
2281     /* Flags for lock or power on */
2282     if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
2283     {
2284         /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
2285         uint32_t maxCCO    = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
2286         uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
2287 
2288         /* Initialize  and power up PLL */
2289         SYSCON->SYSPLLMDEC = maxCCO;
2290         POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
2291 
2292         /* Set mreq to activate */
2293         SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
2294 
2295         /* Delay for 72 uSec @ 12Mhz */
2296         SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2297 
2298         /* clear mreq to prepare for restoring mreq */
2299         SYSCON->SYSPLLMDEC = curSSCTRL;
2300 
2301         /* set original value back and activate */
2302         SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
2303 
2304         /* Enable peripheral states by setting low */
2305         POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
2306     }
2307     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2308     {
2309         while (CLOCK_IsSystemPLLLocked() == false)
2310         {
2311         }
2312     }
2313 
2314     /* Update current programmed PLL rate var */
2315     s_Pll_Freq = pSetup->pllRate;
2316 
2317     return kStatus_PLL_Success;
2318 }
2319 
2320 /* Setup Audio PLL Frequency from pre-calculated value */
2321 /**
2322  * brief	Set Audio PLL output from Audio PLL setup structure (precise frequency)
2323  * param	pSetup	: Pointer to populated PLL setup structure
2324  * return	kStatus_PLL_Success on success, or Audio PLL setup error code
2325  * note	This function will power off the PLL, setup the Audio PLL with the
2326  * new setup data, and then optionally powerup the PLL, wait for Audio PLL lock,
2327  * and adjust system voltages to the new PLL rate. The function will not
2328  * alter any source clocks (ie, main systen clock) that may use the Audio PLL,
2329  * so these should be setup prior to and after exiting the function.
2330  */
CLOCK_SetAudioPLLFreq(const pll_setup_t * pSetup)2331 pll_error_t CLOCK_SetAudioPLLFreq(const pll_setup_t *pSetup)
2332 {
2333     if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
2334     {
2335         /* Turn on the ext clock if system pll input select clk_in */
2336         CLOCK_Enable_SysOsc(true);
2337     }
2338     /* Enable power VD3 for PLLs */
2339     POWER_SetPLL();
2340     /* Power off Audio PLL during setup changes */
2341     POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
2342 
2343     /* Write Audio PLL setup data */
2344     SYSCON->AUDPLLCTRL = pSetup->pllctrl;
2345     SYSCON->AUDPLLFRAC = pSetup->audpllfrac;
2346     SYSCON->AUDPLLFRAC = pSetup->audpllfrac | (1UL << SYSCON_AUDPLLFRAC_REQ_SHIFT); /* latch */
2347     SYSCON->AUDPLLNDEC = pSetup->pllndec;
2348     SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_AUDPLLNDEC_NREQ_SHIFT); /* latch */
2349     SYSCON->AUDPLLPDEC = pSetup->pllpdec;
2350     SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_AUDPLLPDEC_PREQ_SHIFT); /* latch */
2351     SYSCON->AUDPLLMDEC = pSetup->pllmdec;
2352     SYSCON->AUDPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_AUDPLLMDEC_MREQ_SHIFT); /* latch */
2353     SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(1);                            /* disable fractional function */
2354 
2355     /* Flags for lock or power on */
2356     if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
2357     {
2358         /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
2359         uint32_t maxCCO    = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
2360         uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
2361 
2362         /* Initialize  and power up PLL */
2363         SYSCON->SYSPLLMDEC = maxCCO;
2364         POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2365 
2366         /* Set mreq to activate */
2367         SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
2368 
2369         /* Delay for 72 uSec @ 12Mhz */
2370         SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2371 
2372         /* clear mreq to prepare for restoring mreq */
2373         SYSCON->SYSPLLMDEC = curSSCTRL;
2374 
2375         /* set original value back and activate */
2376         SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
2377 
2378         /* Enable peripheral states by setting low */
2379         POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
2380     }
2381     if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
2382     {
2383         while (CLOCK_IsAudioPLLLocked() == false)
2384         {
2385         }
2386     }
2387 
2388     /* Update current programmed PLL rate var */
2389     s_Audio_Pll_Freq = pSetup->pllRate;
2390 
2391     return kStatus_PLL_Success;
2392 }
2393 
2394 /* Setup USB PLL Frequency from pre-calculated value */
2395 /**
2396  * brief	Set USB PLL output from USB PLL setup structure (precise frequency)
2397  * param	pSetup	: Pointer to populated USB PLL setup structure
2398  * return	kStatus_PLL_Success on success, or USB PLL setup error code
2399  * note	This function will power off the USB PLL, setup the PLL with the
2400  * new setup data, and then optionally powerup the USB PLL, wait for USB PLL lock,
2401  * and adjust system voltages to the new USB PLL rate. The function will not
2402  * alter any source clocks (ie, usb pll clock) that may use the USB PLL,
2403  * so these should be setup prior to and after exiting the function.
2404  */
CLOCK_SetUsbPLLFreq(const usb_pll_setup_t * pSetup)2405 pll_error_t CLOCK_SetUsbPLLFreq(const usb_pll_setup_t *pSetup)
2406 {
2407     uint32_t usbpllctrl, fccoHz;
2408     uint8_t msel, psel, nsel;
2409     bool pllDirectInput, pllDirectOutput, pllfbsel;
2410 
2411     msel            = pSetup->msel;
2412     psel            = pSetup->psel;
2413     nsel            = pSetup->nsel;
2414     pllDirectOutput = pSetup->direct;
2415     pllDirectInput  = pSetup->bypass;
2416     pllfbsel        = pSetup->fbsel;
2417 
2418     /* Input clock into the PLL cannot be lower than this */
2419     if (pSetup->inputRate < USB_PLL_LOWER_IN_LIMIT)
2420     {
2421         return kStatus_PLL_InputTooLow;
2422     }
2423 
2424     if (pllfbsel)
2425     {
2426         /*integer_mode: Fout = M*(Fin/N),  Fcco = 2*P*M*(Fin/N) */
2427         fccoHz = (pSetup->inputRate / (nsel + 1UL)) * 2UL * (msel + 1UL) * (1UL << (psel & 3U));
2428 
2429         /* USB PLL CCO out rate cannot be lower than this */
2430         if (fccoHz < USB_PLL_MIN_CCO_FREQ_MHZ)
2431         {
2432             return kStatus_PLL_CCOTooLow;
2433         }
2434         /* USB PLL CCO out rate cannot be Higher than this */
2435         if (fccoHz > USB_PLL_MAX_CCO_FREQ_MHZ)
2436         {
2437             return kStatus_PLL_CCOTooHigh;
2438         }
2439     }
2440     else
2441     {
2442         /* non integer_mode: Fout = M*(Fin/N)/(2*P), Fcco = M * (Fin/N) */
2443         fccoHz = pSetup->inputRate / (nsel + 1UL) * (msel + 1UL);
2444 
2445         /* USB PLL CCO out rate cannot be lower than this */
2446         if (fccoHz < USB_PLL_MIN_CCO_FREQ_MHZ)
2447         {
2448             return kStatus_PLL_CCOTooLow;
2449         }
2450         /* USB PLL CCO out rate cannot be Higher than this */
2451         if (fccoHz > USB_PLL_MAX_CCO_FREQ_MHZ)
2452         {
2453             return kStatus_PLL_CCOTooHigh;
2454         }
2455     }
2456 
2457     /* If configure the USB HOST clock, VD5 power for USB PHY should be enable
2458        before the PLL is working */
2459     /* Turn on the ext clock for usb pll input */
2460     CLOCK_Enable_SysOsc(true);
2461 
2462     /* Enable power VD3 for PLLs */
2463     POWER_SetPLL();
2464 
2465     /* Power on the VD5 for USB PHY */
2466     POWER_SetUsbPhy();
2467 
2468     /* Power off USB PLL during setup changes */
2469     POWER_EnablePD(kPDRUNCFG_PD_USB_PLL);
2470 
2471     /* Write USB PLL setup data */
2472     usbpllctrl = USB_PLL_NSEL_VAL_SET(nsel) |                                  /* NSEL VALUE */
2473                  USB_PLL_PSEL_VAL_SET(psel) |                                  /* PSEL VALUE */
2474                  USB_PLL_MSEL_VAL_SET(msel) |                                  /* MSEL VALUE */
2475                  (uint32_t)pllDirectInput << SYSCON_USBPLLCTRL_BYPASS_SHIFT |  /* BYPASS DISABLE */
2476                  (uint32_t)pllDirectOutput << SYSCON_USBPLLCTRL_DIRECT_SHIFT | /* DIRECTO DISABLE */
2477                  (uint32_t)pllfbsel << SYSCON_USBPLLCTRL_FBSEL_SHIFT;          /* FBSEL SELECT */
2478 
2479     SYSCON->USBPLLCTRL = usbpllctrl;
2480 
2481     POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
2482 
2483     /* Delay for 72 uSec @ 12Mhz for the usb pll to lock */
2484     SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2485     if (false == pllDirectInput)
2486     {
2487         while (CLOCK_IsUsbPLLLocked() == false)
2488         {
2489         }
2490     }
2491     CLOCK_GetUsbPLLOutFromSetupUpdate(pSetup);
2492     return kStatus_PLL_Success;
2493 }
2494 
2495 /* Set System PLL clock based on the input frequency and multiplier */
2496 /*! brief	Set PLL output based on the multiplier and input frequency
2497  * param	multiply_by	: multiplier
2498  * param	input_freq	: Clock input frequency of the PLL
2499  * return	Nothing
2500  * note	Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
2501  * function does not disable or enable PLL power, wait for PLL lock,
2502  * or adjust system voltages. These must be done in the application.
2503  * The function will not alter any source clocks (ie, main systen clock)
2504  * that may use the PLL, so these should be setup prior to and after
2505  * exiting the function.
2506  */
CLOCK_SetupSystemPLLMult(uint32_t multiply_by,uint32_t input_freq)2507 void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq)
2508 {
2509     uint32_t cco_freq = input_freq * multiply_by;
2510     uint32_t pdec     = 1U;
2511     uint32_t selr;
2512     uint32_t seli;
2513     uint32_t selp;
2514     uint32_t mdec, ndec;
2515 
2516     uint32_t directo = SYSCON_SYSPLLCTRL_DIRECTO(1);
2517 
2518     while (cco_freq < 275000000U)
2519     {
2520         multiply_by <<= 1U; /* double value in each iteration */
2521         pdec <<= 1U;        /* correspondingly double pdec to cancel effect of double msel */
2522         cco_freq = input_freq * multiply_by;
2523     }
2524     selr = 0U;
2525     if (multiply_by < 60U)
2526     {
2527         seli = (multiply_by & 0x3cU) + 4U;
2528         selp = (multiply_by >> 1U) + 1U;
2529     }
2530     else
2531     {
2532         selp = 31U;
2533         if (multiply_by > 16384U)
2534         {
2535             seli = 1U;
2536         }
2537         else if (multiply_by > 8192U)
2538         {
2539             seli = 2U;
2540         }
2541         else if (multiply_by > 2048U)
2542         {
2543             seli = 4U;
2544         }
2545         else if (multiply_by >= 501U)
2546         {
2547             seli = 8U;
2548         }
2549         else
2550         {
2551             seli = 4U * (1024U / (multiply_by + 9U));
2552         }
2553     }
2554 
2555     if (pdec > 1U)
2556     {
2557         directo = 0U;        /* use post divider */
2558         pdec    = pdec / 2U; /* Account for minus 1 encoding */
2559                              /* Translate P value */
2560         switch (pdec)
2561         {
2562             case 1U:
2563                 pdec = 0x62U; /* 1  * 2 */
2564                 break;
2565             case 2U:
2566                 pdec = 0x42U; /* 2  * 2 */
2567                 break;
2568             case 4U:
2569                 pdec = 0x02U; /* 4  * 2 */
2570                 break;
2571             case 8U:
2572                 pdec = 0x0bU; /* 8  * 2 */
2573                 break;
2574             case 16U:
2575                 pdec = 0x11U; /* 16 * 2 */
2576                 break;
2577             case 32U:
2578                 pdec = 0x08U; /* 32 * 2 */
2579                 break;
2580             default:
2581                 pdec = 0x08U;
2582                 break;
2583         }
2584     }
2585 
2586     mdec = PLL_MDEC_VAL_SET(pllEncodeM(multiply_by));
2587     ndec = 0x302U; /* pre divided by 1 (hardcoded) */
2588 
2589     SYSCON->SYSPLLCTRL = directo | (selr << SYSCON_SYSPLLCTRL_SELR_SHIFT) | (seli << SYSCON_SYSPLLCTRL_SELI_SHIFT) |
2590                          (selp << SYSCON_SYSPLLCTRL_SELP_SHIFT);
2591     SYSCON->SYSPLLPDEC = pdec | (1UL << 7U);  /* set Pdec value and assert preq */
2592     SYSCON->SYSPLLNDEC = ndec | (1UL << 10U); /* set Pdec value and assert preq */
2593     SYSCON->SYSPLLMDEC = (1UL << 17U) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */
2594 }
2595 
2596 /* Enable USB DEVICE FULL SPEED clock */
2597 /*! brief Enable USB Device FS clock.
2598  * param	src	: clock source
2599  * param	freq: clock frequency
2600  * Enable USB Device Full Speed clock.
2601  */
CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src,uint32_t freq)2602 bool CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src, uint32_t freq)
2603 {
2604     bool ret = true;
2605 
2606     CLOCK_DisableClock(kCLOCK_Usbd0);
2607 
2608     if (kCLOCK_UsbSrcFro == src)
2609     {
2610         switch (freq)
2611         {
2612             case 96000000U:
2613                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2614                 break;
2615 
2616             case 48000000U:
2617                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
2618                 break;
2619 
2620             default:
2621                 ret = false;
2622                 break;
2623         }
2624         /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
2625         SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
2626                           SYSCON_FROCTRL_USBCLKADJ_MASK;
2627         /* Select FRO 96 or 48 MHz */
2628         CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
2629     }
2630     else
2631     {
2632         /*Set the USB PLL as the Usb0 CLK*/
2633         POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
2634 
2635         usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
2636 
2637         (void)CLOCK_SetUsbPLLFreq(&pll_setup);
2638         CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
2639         CLOCK_AttachClk(kUSB_PLL_to_USB0_CLK);
2640         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2641     }
2642     CLOCK_EnableClock(kCLOCK_Usbd0);
2643     CLOCK_EnableClock(kCLOCK_UsbRam1);
2644 
2645     return ret;
2646 }
2647 
2648 /* Enable USB HOST FULL SPEED clock */
2649 /*! brief Enable USB HOST FS clock.
2650  * param	src	: clock source
2651  * param	freq: clock frequency
2652  * Enable USB HOST Full Speed clock.
2653  */
CLOCK_EnableUsbfs0HostClock(clock_usb_src_t src,uint32_t freq)2654 bool CLOCK_EnableUsbfs0HostClock(clock_usb_src_t src, uint32_t freq)
2655 {
2656     bool ret = true;
2657 
2658     CLOCK_DisableClock(kCLOCK_Usbhmr0);
2659     CLOCK_DisableClock(kCLOCK_Usbhsl0);
2660 
2661     if (kCLOCK_UsbSrcFro == src)
2662     {
2663         switch (freq)
2664         {
2665             case 96000000U:
2666                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2667                 break;
2668 
2669             case 48000000U:
2670                 CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
2671                 break;
2672 
2673             default:
2674                 ret = false;
2675                 break;
2676         }
2677         /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
2678         SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
2679                           SYSCON_FROCTRL_USBCLKADJ_MASK;
2680         /* Select FRO 96 or 48 MHz */
2681         CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
2682     }
2683     else
2684     {
2685         /*Set the USB PLL as the Usb0 CLK*/
2686         POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
2687 
2688         usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
2689 
2690         (void)CLOCK_SetUsbPLLFreq(&pll_setup);
2691         CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
2692         CLOCK_AttachClk(kUSB_PLL_to_USB0_CLK);
2693         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2694     }
2695     CLOCK_EnableClock(kCLOCK_Usbhmr0);
2696     CLOCK_EnableClock(kCLOCK_Usbhsl0);
2697     CLOCK_EnableClock(kCLOCK_UsbRam1);
2698 
2699     return ret;
2700 }
2701 
2702 /* Enable USB DEVICE HIGH SPEED clock */
2703 /*! brief Enable USB Device HS clock.
2704  * param	src	: clock source
2705  * param	freq: clock frequency
2706  * Enable USB Device High Speed clock.
2707  */
CLOCK_EnableUsbhs0DeviceClock(clock_usb_src_t src,uint32_t freq)2708 bool CLOCK_EnableUsbhs0DeviceClock(clock_usb_src_t src, uint32_t freq)
2709 {
2710     bool ret = true;
2711     CLOCK_DisableClock(kCLOCK_Usbd1);
2712     /* Power on the VD5 for USB PHY */
2713     POWER_SetUsbPhy();
2714     if (kCLOCK_UsbSrcFro == src)
2715     {
2716         switch (freq)
2717         {
2718             case 96000000U:
2719                 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2720                 break;
2721 
2722             case 48000000U:
2723                 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
2724                 break;
2725 
2726             default:
2727                 ret = false;
2728                 break;
2729         }
2730         /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
2731         SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
2732                           SYSCON_FROCTRL_USBCLKADJ_MASK;
2733         /* Select FRO 96 or 48 MHz */
2734         CLOCK_AttachClk(kFRO_HF_to_USB1_CLK);
2735     }
2736     else
2737     {
2738         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2739         usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
2740 
2741         (void)CLOCK_SetUsbPLLFreq(&pll_setup);
2742 
2743         /* Select USB PLL output as USB clock src */
2744         CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false);
2745         CLOCK_AttachClk(kUSB_PLL_to_USB1_CLK);
2746     }
2747 
2748     SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2749     /* Enable USB1D and USB1RAM */
2750     CLOCK_EnableClock(kCLOCK_Usbd1);
2751     CLOCK_EnableClock(kCLOCK_UsbRam1);
2752     POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* Turn on power for USB PHY */
2753     return ret;
2754 }
2755 
2756 /* Enable USB HOST HIGH SPEED clock */
2757 /*! brief Enable USB HOST HS clock.
2758  * param	src	: clock source
2759  * param	freq: clock frequency
2760  * Enable USB HOST High Speed clock.
2761  */
CLOCK_EnableUsbhs0HostClock(clock_usb_src_t src,uint32_t freq)2762 bool CLOCK_EnableUsbhs0HostClock(clock_usb_src_t src, uint32_t freq)
2763 {
2764     bool ret = true;
2765     CLOCK_DisableClock(kCLOCK_Usbh1);
2766     /* Power on the VD5 for USB PHY */
2767     POWER_SetUsbPhy();
2768     if (kCLOCK_UsbSrcFro == src)
2769     {
2770         switch (freq)
2771         {
2772             case 96000000U:
2773                 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */
2774                 break;
2775 
2776             case 48000000U:
2777                 CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */
2778                 break;
2779 
2780             default:
2781                 ret = false;
2782                 break;
2783         }
2784         /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
2785         SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
2786                           SYSCON_FROCTRL_USBCLKADJ_MASK;
2787         /* Select FRO 96 or 48 MHz */
2788         CLOCK_AttachClk(kFRO_HF_to_USB1_CLK);
2789     }
2790     else
2791     {
2792         SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2793         usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
2794 
2795         (void)CLOCK_SetUsbPLLFreq(&pll_setup);
2796 
2797         /* Select USB PLL output as USB clock src */
2798         CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false);
2799         CLOCK_AttachClk(kUSB_PLL_to_USB1_CLK);
2800     }
2801 
2802     SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
2803     /* Enable USBh1 and USB1RAM */
2804     CLOCK_EnableClock(kCLOCK_Usbh1);
2805     CLOCK_EnableClock(kCLOCK_UsbRam1);
2806     POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* Turn on power for USB PHY */
2807     return ret;
2808 }
2809