1 /*
2 * Copyright 2020-2024, NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_clock.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.clock"
17 #endif
18
19 /* Each loop costs 3 cpu cycles */
20 #define CLOCK_DELAY_LOOPS(cpuFreq, delayFreq, delayCycles) \
21 ((((cpuFreq) + (delayFreq)-1U) / (delayFreq)) * (delayCycles) / 3U)
22
23 #define CLOCK_KHZ(freq) ((freq)*1000UL)
24 #define CLOCK_MHZ(freq) (CLOCK_KHZ(freq) * 1000UL)
25
26 /*******************************************************************************
27 * Variables
28 ******************************************************************************/
29 /* External CLK_IN pin clock frequency. */
30 volatile uint32_t g_clkinFreq = 0U;
31 /* External MCLK in (mclk_in) clock frequency. If not used,
32 set this to 0. Otherwise, set it to the exact rate in Hz this pin is
33 being driven at.*/
34 volatile uint32_t g_mclkinFreq = 0U;
35
36 static const uint32_t s_avpllFreq[] = {
37 0U,
38 CLOCK_KHZ(2048UL), /*!< AVPLL channel frequency 2.048MHz */
39 CLOCK_KHZ(4096UL), /*!< AVPLL channel frequency 4.096MHz */
40 CLOCK_KHZ(6144UL), /*!< AVPLL channel frequency 6.144MHz */
41 CLOCK_KHZ(8192UL), /*!< AVPLL channel frequency 8.192MHz */
42 11289600UL, /*!< AVPLL channel frequency 11.2896MHz */
43 CLOCK_MHZ(12UL), /*!< AVPLL channel frequency 12MHz */
44 CLOCK_KHZ(12288UL), /*!< AVPLL channel frequency 12.288MHz */
45 CLOCK_KHZ(24576UL), /*!< AVPLL channel frequency 24.576MHz */
46 CLOCK_MHZ(64UL), /*!< AVPLL channel frequency 64MHz */
47 CLOCK_KHZ(98304UL), /*!< AVPLL channel frequency 98.304MHz */
48 };
49
50 static const uint32_t s_avpllFreqOff[] = {
51 0U, /*!< AVPLL channel unchanged */
52 0x53U, /*!< AVPLL channel frequency 2.048MHz */
53 0x1050U, /*!< AVPLL channel frequency 4.096MHz */
54 0x4145DU, /*!< AVPLL channel frequency 6.144MHz */
55 0x4145DU, /*!< AVPLL channel frequency 8.192MHz */
56 0x38B3U, /*!< AVPLL channel frequency 11.2896MHz */
57 0U, /*!< AVPLL channel frequency 12MHz */
58 0x4145DU, /*!< AVPLL channel frequency 12.288MHz */
59 0x4145DU, /*!< AVPLL channel frequency 24.576MHz */
60 0xCCCDU, /*!< AVPLL channel frequency 64MHz */
61 0x4145DU, /*!< AVPLL channel frequency 98.304MHz */
62 };
63
64 static const uint32_t s_avpllPostDiv[] = {
65 0U, /*!< AVPLL channel unchanged */
66 791U, /*!< AVPLL channel frequency 2.048MHz */
67 395U, /*!< AVPLL channel frequency 4.096MHz */
68 264U, /*!< AVPLL channel frequency 6.144MHz */
69 198U, /*!< AVPLL channel frequency 8.192MHz */
70 143U, /*!< AVPLL channel frequency 11.2896MHz */
71 135U, /*!< AVPLL channel frequency 12MHz */
72 132U, /*!< AVPLL channel frequency 12.288MHz */
73 66U, /*!< AVPLL channel frequency 24.576MHz */
74 25U, /*!< AVPLL channel frequency 64MHz */
75 16U, /*!< AVPLL channel frequency 98.304MHz */
76 };
77
78 static const uint32_t s_avpllPostDiv0p5[] = {
79 0U, /*!< AVPLL channel unchanged */
80 0U, /*!< AVPLL channel frequency 2.048MHz */
81 0U, /*!< AVPLL channel frequency 4.096MHz */
82 0U, /*!< AVPLL channel frequency 6.144MHz */
83 0U, /*!< AVPLL channel frequency 8.192MHz */
84 0U, /*!< AVPLL channel frequency 11.2896MHz */
85 0U, /*!< AVPLL channel frequency 12MHz */
86 0U, /*!< AVPLL channel frequency 12.288MHz */
87 0U, /*!< AVPLL channel frequency 24.576MHz */
88 0U, /*!< AVPLL channel frequency 64MHz */
89 1U, /*!< AVPLL channel frequency 98.304MHz */
90 };
91
92 /*******************************************************************************
93 * Prototypes
94 ******************************************************************************/
95
96 /*******************************************************************************
97 * Code
98 ******************************************************************************/
99 /* Workaround iar/armgcc optimization issue */
100 __attribute__((__noinline__))
CLOCK_Delay(uint32_t loop)101 static void CLOCK_Delay(uint32_t loop)
102 {
103 if (loop > 0U)
104 {
105 __ASM volatile(
106 "1: \n"
107 " SUBS %0, %0, #1 \n"
108 " CMP %0, #0 \n"
109 " BNE 1b \n"
110 :
111 : "r"(loop));
112 }
113 }
114
CLOCK_DelayUs(uint32_t us)115 static void CLOCK_DelayUs(uint32_t us)
116 {
117 uint32_t instNum;
118
119 instNum = ((SystemCoreClock + 999999UL) / 1000000UL) * us;
120 CLOCK_Delay((instNum + 2U) / 3U);
121 }
122
123 /*! @brief Return Frequency of t3pll_mci_48_60m_irc
124 * @return Frequency of t3pll_mci_48_60m_irc
125 */
CLOCK_GetT3PllMciIrcClkFreq(void)126 uint32_t CLOCK_GetT3PllMciIrcClkFreq(void)
127 {
128 uint32_t freq = 0U;
129
130 if ((SYSPLL_T3->CLKTREE_CTRL_SIX_REG & 0xFU) == 0x5U)
131 {
132 freq = CLOCK_MHZ(2560UL) / 43UL;
133 }
134 else if ((SYSPLL_T3->CLKTREE_CTRL_SIX_REG & 0xFU) == 0xAU)
135 {
136 freq = CLOCK_MHZ(2560UL) / 53UL;
137 }
138 else
139 {
140 /* Only 48MHz and 60MHz is allowed */
141 assert(false);
142 }
143
144 return freq;
145 }
146
147 /*! @brief Return Frequency of t3pll_mci_213p3m
148 * @return Frequency of t3pll_mci_213p3m
149 */
CLOCK_GetT3PllMci213mClkFreq(void)150 uint32_t CLOCK_GetT3PllMci213mClkFreq(void)
151 {
152 uint32_t freq = CLOCK_KHZ(213300UL);
153 return freq;
154 }
155
156 /*! @brief Return Frequency of t3pll_mci_256m
157 * @return Frequency of t3pll_mci_256m
158 */
CLOCK_GetT3PllMci256mClkFreq(void)159 uint32_t CLOCK_GetT3PllMci256mClkFreq(void)
160 {
161 uint32_t freq = CLOCK_MHZ(256UL);
162 return freq;
163 }
164
165 /*! @brief Return Frequency of t3pll_mci_flexspi_clk
166 * @return Frequency of t3pll_mci_flexspi_clk
167 */
CLOCK_GetT3PllMciFlexspiClkFreq(void)168 uint32_t CLOCK_GetT3PllMciFlexspiClkFreq(void)
169 {
170 uint32_t freq = CLOCK_MHZ(365UL);
171 ;
172 return freq;
173 }
174
CLOCK_GetTcpuFvcoFreq(void)175 static uint32_t CLOCK_GetTcpuFvcoFreq(void)
176 {
177 uint32_t freq = 0UL;
178 uint32_t steps;
179
180 steps = (SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_TCPU_FBDIV_MASK) >> SYSCTL2_PLL_CTRL_TCPU_FBDIV_SHIFT;
181
182 if ((CLK_XTAL_OSC_CLK == CLK_XTAL_OSC_CLK_40000KHZ) && (steps >= 75UL) && (steps <= 96UL))
183 {
184 /* Fbdiv from 75 to 96, step 40MHz */
185 steps -= 75UL;
186 freq = CLOCK_MHZ(3000UL) + steps * CLOCK_MHZ(40UL);
187 }
188 else if ((CLK_XTAL_OSC_CLK == CLK_XTAL_OSC_CLK_38400KHZ) && (steps >= 78UL) && (steps <= 100UL))
189 {
190 /* Fbdiv from 78 to 100, step 38.4MHz */
191 steps -= 78UL;
192 freq = CLOCK_KHZ(2995200UL) + steps * CLOCK_KHZ(38400UL);
193 }
194 else
195 {
196 assert(false);
197 }
198
199 return freq;
200 }
201
202 /*! @brief Return Frequency of tcpu_mci_clk
203 * return Frequency of tcpu_mci_clk
204 */
CLOCK_GetTcpuMciClkFreq(void)205 uint32_t CLOCK_GetTcpuMciClkFreq(void)
206 {
207 uint32_t freq = CLOCK_GetTcpuFvcoFreq() / 12UL;
208 return freq;
209 }
210
211 /*! @brief Return Frequency of tcpu_mci_flexspi_clk
212 * @return Frequency of tcpu_mci_flexspi_clk
213 */
CLOCK_GetTcpuMciFlexspiClkFreq(void)214 uint32_t CLOCK_GetTcpuMciFlexspiClkFreq(void)
215 {
216 uint32_t div =
217 (SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_TCPU_FLEXSPI_CLK_SEL_MASK) >> SYSCTL2_PLL_CTRL_TCPU_FLEXSPI_CLK_SEL_SHIFT;
218
219 return CLOCK_GetTcpuFvcoFreq() / (12UL - div);
220 }
221
222 /*! @brief Return Frequency of tddr_mci_flexspi_clk
223 * @return Frequency of tddr_mci_flexspi_clk
224 */
CLOCK_GetTddrMciFlexspiClkFreq(void)225 uint32_t CLOCK_GetTddrMciFlexspiClkFreq(void)
226 {
227 uint32_t div =
228 (SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_TDDR_FLEXSPI_CLK_SEL_MASK) >> SYSCTL2_PLL_CTRL_TDDR_FLEXSPI_CLK_SEL_SHIFT;
229 /* TDDR FVCO fixed to 3.2GHz */
230 return CLOCK_MHZ(3200UL) / (11UL - div);
231 }
232
233 /*! @brief Return Frequency of tddr_mci_enet_clk
234 * @return Frequency of tddr_mci_enet_clk
235 */
CLOCK_GetTddrMciEnetClkFreq(void)236 uint32_t CLOCK_GetTddrMciEnetClkFreq(void)
237 {
238 uint32_t freq = CLOCK_MHZ(50UL);
239 return freq;
240 }
241
242 /*!
243 * @brief Enable the clock for specific IP.
244 *
245 * @param clk Which clock to enable, see @ref clock_ip_name_t.
246 */
CLOCK_EnableClock(clock_ip_name_t clk)247 void CLOCK_EnableClock(clock_ip_name_t clk)
248 {
249 uint32_t index;
250
251 if (clk == kCLOCK_RefClkCauSlp)
252 {
253 PMU->CAU_SLP_CTRL &= ~PMU_CAU_SLP_CTRL_CAU_SOC_SLP_CG_MASK;
254 while ((PMU->CAU_SLP_CTRL & PMU_CAU_SLP_CTRL_SOC_SLP_RDY_MASK) == 0U)
255 {
256 }
257 }
258 else if (((uint32_t)clk & SYS_CLK_GATE_FLAG_MASK) != 0U)
259 {
260 SYSCTL2->SOURCE_CLK_GATE &= ~SYS_CLK_GATE_BIT_MASK(clk);
261 /* Delay 2 40MHz cycles to make it ready. */
262 CLOCK_Delay(CLOCK_DELAY_LOOPS(SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY, 40000000UL, 2U));
263 }
264 else
265 {
266 index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
267
268 switch (index)
269 {
270 case CLK_CTL0_PSCCTL0:
271 CLKCTL0->PSCCTL0_SET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
272 break;
273 case CLK_CTL0_PSCCTL1:
274 CLKCTL0->PSCCTL1_SET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
275 break;
276 case CLK_CTL0_PSCCTL2:
277 CLKCTL0->PSCCTL2_SET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
278 break;
279 case CLK_CTL1_PSCCTL0:
280 CLKCTL1->PSCCTL0_SET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
281 break;
282 case CLK_CTL1_PSCCTL1:
283 CLKCTL1->PSCCTL1_SET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
284 break;
285 case CLK_CTL1_PSCCTL2:
286 CLKCTL1->PSCCTL2_SET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
287 break;
288 default:
289 assert(false);
290 break;
291 }
292
293 if (clk == kCLOCK_Gau)
294 {
295 SYSCTL2->GAU_CTRL = SYSCTL2_GAU_CTRL_GAU_GPDAC_MCLK_EN_MASK | SYSCTL2_GAU_CTRL_GAU_BG_MCLK_EN_MASK |
296 SYSCTL2_GAU_CTRL_GAU_GPADC1_MCLK_EN_MASK | SYSCTL2_GAU_CTRL_GAU_GPADC0_MCLK_EN_MASK |
297 SYSCTL2_GAU_CTRL_GAU_ACOMP_MCLK_EN_MASK;
298 }
299 }
300 }
301
302 /*!
303 * @brief Disable the clock for specific IP.
304 *
305 * @param clk Which clock to disable, see @ref clock_ip_name_t.
306 */
CLOCK_DisableClock(clock_ip_name_t clk)307 void CLOCK_DisableClock(clock_ip_name_t clk)
308 {
309 uint32_t index;
310
311 if (clk == kCLOCK_RefClkCauSlp)
312 {
313 PMU->CAU_SLP_CTRL |= PMU_CAU_SLP_CTRL_CAU_SOC_SLP_CG_MASK;
314 }
315 else if (((uint32_t)clk & SYS_CLK_GATE_FLAG_MASK) != 0U)
316 {
317 SYSCTL2->SOURCE_CLK_GATE |= SYS_CLK_GATE_BIT_MASK(clk);
318 }
319 else
320 {
321 index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
322 switch (index)
323 {
324 case CLK_CTL0_PSCCTL0:
325 CLKCTL0->PSCCTL0_CLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
326 break;
327 case CLK_CTL0_PSCCTL1:
328 CLKCTL0->PSCCTL1_CLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
329 break;
330 case CLK_CTL0_PSCCTL2:
331 CLKCTL0->PSCCTL2_CLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
332 break;
333 case CLK_CTL1_PSCCTL0:
334 CLKCTL1->PSCCTL0_CLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
335 break;
336 case CLK_CTL1_PSCCTL1:
337 CLKCTL1->PSCCTL1_CLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
338 break;
339 case CLK_CTL1_PSCCTL2:
340 CLKCTL1->PSCCTL2_CLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
341 break;
342 default:
343 assert(false);
344 break;
345 }
346
347 if (clk == kCLOCK_Gau)
348 {
349 SYSCTL2->GAU_CTRL = 0U;
350 }
351 }
352 }
353
354 /**
355 * @brief Configure the clock selection muxes.
356 * @param connection : Clock to be configured.
357 */
CLOCK_AttachClk(clock_attach_id_t connection)358 void CLOCK_AttachClk(clock_attach_id_t connection)
359 {
360 bool final_descriptor = false;
361 uint32_t i;
362 volatile uint32_t *pClkSel;
363
364 if (((uint32_t)connection & PMU_TUPLE_MUX_AVAIL) != 0U)
365 {
366 *PMU_TUPLE_REG(PMU, connection) = PMU_TUPLE_SEL(connection);
367 }
368 else if (((uint32_t)connection & CLKOUT_TUPLE_MUX_AVAIL) != 0U)
369 {
370 CLKCTL1->CLKOUTSEL0 = CLKCTL1_CLKOUTSEL0_SEL(((uint32_t)connection >> 4U) & 0x7U);
371 CLKCTL1->CLKOUTSEL1 = CLKCTL1_CLKOUTSEL1_SEL(((uint32_t)connection >> 8U) & 0x7U);
372 CLKCTL1->CLKOUTSEL2 = CLKCTL1_CLKOUTSEL2_SEL(((uint32_t)connection >> 12U) & 0x7U);
373 }
374 else
375 {
376 for (i = 0U; (i < 2U) && (!final_descriptor); i++)
377 {
378 connection =
379 (clock_attach_id_t)(uint32_t)(((uint32_t)connection) >> (i * 16U)); /*!< pick up next descriptor */
380
381 if ((((uint32_t)connection) & CLKCTL1_TUPLE_FLAG_MASK) != 0UL)
382 {
383 pClkSel = CLKCTL_TUPLE_REG(CLKCTL1, connection);
384 }
385 else
386 {
387 pClkSel = CLKCTL_TUPLE_REG(CLKCTL0, connection);
388 }
389
390 if ((((uint32_t)connection) & 0xFFCU) != 0UL)
391 {
392 *pClkSel = CLKCTL_TUPLE_SEL(connection);
393 }
394 else
395 {
396 final_descriptor = true;
397 }
398 }
399 }
400 }
401
402 /**
403 * @brief Setup clock dividers.
404 * @param name : Clock divider name
405 * @param divider : Value to be divided.
406 */
CLOCK_SetClkDiv(clock_div_name_t name,uint32_t divider)407 void CLOCK_SetClkDiv(clock_div_name_t name, uint32_t divider)
408 {
409 volatile uint32_t *pClkDiv;
410
411 if ((((uint32_t)name) & CLKCTL1_TUPLE_FLAG_MASK) != 0UL)
412 {
413 pClkDiv = CLKCTL_TUPLE_REG(CLKCTL1, name);
414 }
415 else
416 {
417 pClkDiv = CLKCTL_TUPLE_REG(CLKCTL0, name);
418 }
419 /* Reset the divider counter */
420 *pClkDiv |= 1UL << 29U;
421
422 if (divider == 0U) /*!< halt */
423 {
424 *pClkDiv |= 1UL << 30U;
425 }
426 else
427 {
428 *pClkDiv = divider - 1U;
429
430 while (((*pClkDiv) & 0x80000000U) != 0UL)
431 {
432 }
433 }
434 }
435
436 /*! brief Return Frequency of selected clock
437 * return Frequency of selected clock
438 */
CLOCK_GetFreq(clock_name_t clockName)439 uint32_t CLOCK_GetFreq(clock_name_t clockName)
440 {
441 uint32_t freq;
442 switch (clockName)
443 {
444 case kCLOCK_CoreSysClk:
445 case kCLOCK_BusClk:
446 freq = CLOCK_GetCoreSysClkFreq();
447 break;
448 case kCLOCK_MclkClk:
449 freq = CLOCK_GetMclkClkFreq();
450 break;
451 default:
452 freq = 0U;
453 break;
454 }
455 return freq;
456 }
457
458 /*! @brief Return Frequency of High-Freq output of FRO
459 * @return Frequency of High-Freq output of FRO
460 */
CLOCK_GetFFroFreq(void)461 uint32_t CLOCK_GetFFroFreq(void)
462 {
463 return CLOCK_GetT3PllMciIrcClkFreq();
464 }
465
466 /*! @brief Return Frequency of SFRO
467 * @return Frequency of SFRO
468 */
CLOCK_GetSFroFreq(void)469 uint32_t CLOCK_GetSFroFreq(void)
470 {
471 return CLOCK_GetT3PllMci256mClkFreq() / 16U;
472 }
473
474 /*! @brief Return Frequency of AUDIO PLL (AVPLL CH1)
475 * @return Frequency of AUDIO PLL
476 */
CLOCK_GetAvPllCh1Freq(void)477 uint32_t CLOCK_GetAvPllCh1Freq(void)
478 {
479 uint32_t postdiv =
480 (SYSCTL2->AVPLL_CTRL5 & SYSCTL2_AVPLL_CTRL5_POSTDIV_C1_MASK) >> SYSCTL2_AVPLL_CTRL5_POSTDIV_C1_SHIFT;
481 uint32_t i;
482 uint32_t freq = 0U;
483
484 for (i = 1U; i < ARRAY_SIZE(s_avpllPostDiv); i++)
485 {
486 if (s_avpllPostDiv[i] == postdiv)
487 {
488 freq = s_avpllFreq[i];
489 break;
490 }
491 }
492
493 return freq;
494 }
495
496 /*! @brief Return Frequency of AVPLL CH2
497 * @return Frequency of AVPLL CH2
498 */
CLOCK_GetAvPllCh2Freq(void)499 uint32_t CLOCK_GetAvPllCh2Freq(void)
500 {
501 uint32_t postdiv =
502 (SYSCTL2->AVPLL_CTRL11 & SYSCTL2_AVPLL_CTRL11_POSTDIV_C2_MASK) >> SYSCTL2_AVPLL_CTRL11_POSTDIV_C2_SHIFT;
503 uint32_t i;
504 uint32_t freq = 0U;
505
506 for (i = 1U; i < ARRAY_SIZE(s_avpllPostDiv); i++)
507 {
508 if (s_avpllPostDiv[i] == postdiv)
509 {
510 freq = s_avpllFreq[i];
511 break;
512 }
513 }
514
515 return freq;
516 }
517
CLOCK_GetMainPllClkFreq(void)518 static uint32_t CLOCK_GetMainPllClkFreq(void)
519 {
520 return CLOCK_GetTcpuMciClkFreq() / ((CLKCTL0->MAINPLLCLKDIV & CLKCTL0_MAINPLLCLKDIV_DIV_MASK) + 1U);
521 }
522
CLOCK_GetAux0PllClkFreq(void)523 static uint32_t CLOCK_GetAux0PllClkFreq(void)
524 {
525 return CLOCK_GetTcpuMciClkFreq() / ((CLKCTL0->AUX0PLLCLKDIV & CLKCTL0_AUX0PLLCLKDIV_DIV_MASK) + 1U);
526 }
527
CLOCK_GetAux1PllClkFreq(void)528 static uint32_t CLOCK_GetAux1PllClkFreq(void)
529 {
530 return CLOCK_GetT3PllMci213mClkFreq() / ((CLKCTL0->AUX1PLLCLKDIV & CLKCTL0_AUX1PLLCLKDIV_DIV_MASK) + 1U);
531 }
532
CLOCK_GetAudioPllClkFreq(void)533 static uint32_t CLOCK_GetAudioPllClkFreq(void)
534 {
535 return CLOCK_GetAvPllCh1Freq() / ((CLKCTL1->AUDIOPLLCLKDIV & CLKCTL1_AUDIOPLLCLKDIV_DIV_MASK) + 1U);
536 }
537
538 /* Get MAIN Clk */
539 /*! @brief Return Frequency of main clk
540 * @return Frequency of main clk
541 */
CLOCK_GetMainClkFreq(void)542 uint32_t CLOCK_GetMainClkFreq(void)
543 {
544 uint32_t freq = 0U;
545
546 switch ((CLKCTL0->MAINCLKSELB) & CLKCTL0_MAINCLKSELB_SEL_MASK)
547 {
548 case CLKCTL0_MAINCLKSELB_SEL(0):
549 switch ((CLKCTL0->MAINCLKSELA) & CLKCTL0_MAINCLKSELA_SEL_MASK)
550 {
551 case CLKCTL0_MAINCLKSELA_SEL(0):
552 freq = CLOCK_GetSysOscFreq();
553 break;
554 case CLKCTL0_MAINCLKSELA_SEL(1):
555 freq = CLOCK_GetFFroFreq() / 4U;
556 break;
557 case CLKCTL0_MAINCLKSELA_SEL(2):
558 freq = CLOCK_GetLpOscFreq();
559 break;
560 case CLKCTL0_MAINCLKSELA_SEL(3):
561 freq = CLOCK_GetFFroFreq();
562 break;
563 default:
564 freq = 0U;
565 break;
566 }
567 break;
568
569 case CLKCTL0_MAINCLKSELB_SEL(1):
570 freq = CLOCK_GetSFroFreq();
571 break;
572
573 case CLKCTL0_MAINCLKSELB_SEL(2):
574 freq = CLOCK_GetMainPllClkFreq();
575 break;
576
577 case CLKCTL0_MAINCLKSELB_SEL(3):
578 freq = CLOCK_GetClk32KFreq();
579 break;
580
581 default:
582 freq = 0U;
583 break;
584 }
585
586 return freq;
587 }
588
589 /* Get Core/Bus Clk */
590 /*! @brief Return Frequency of core/bus clk
591 * @return Frequency of core/bus clk
592 */
CLOCK_GetCoreSysClkFreq(void)593 uint32_t CLOCK_GetCoreSysClkFreq(void)
594 {
595 return CLOCK_GetMainClkFreq() / ((CLKCTL0->SYSCPUAHBCLKDIV & CLKCTL0_SYSCPUAHBCLKDIV_DIV_MASK) + 1U);
596 }
597
598 /*! @brief Return Frequency of systick clk
599 * @return Frequency of systick clk
600 */
CLOCK_GetSystickClkFreq(void)601 uint32_t CLOCK_GetSystickClkFreq(void)
602 {
603 uint32_t freq = 0U;
604
605 switch (CLKCTL0->SYSTICKFCLKSEL)
606 {
607 case CLKCTL0_SYSTICKFCLKSEL_SEL(0):
608 freq = CLOCK_GetMainClkFreq() / ((CLKCTL0->SYSTICKFCLKDIV & CLKCTL0_SYSTICKFCLKDIV_DIV_MASK) + 1U);
609 break;
610
611 case CLKCTL0_SYSTICKFCLKSEL_SEL(1):
612 freq = CLOCK_GetLpOscFreq();
613 break;
614
615 case CLKCTL0_SYSTICKFCLKSEL_SEL(2):
616 freq = CLOCK_GetClk32KFreq();
617 break;
618
619 case CLKCTL0_SYSTICKFCLKSEL_SEL(3):
620 freq = CLOCK_GetSFroFreq();
621 break;
622
623 default:
624 freq = 0U;
625 break;
626 }
627
628 return freq;
629 }
630
631 /* Get FRG Clk */
632 /*! @brief Return Input frequency for the Fractional baud rate generator
633 * @return Input Frequency for FRG
634 */
CLOCK_GetFRGClock(uint32_t id)635 uint32_t CLOCK_GetFRGClock(uint32_t id)
636 {
637 uint32_t freq = 0U;
638 uint32_t frgPllDiv = 1U;
639 uint32_t clkSel = 0U;
640 uint32_t frgDiv = 0U;
641 uint32_t frgMul = 0U;
642
643 if (id <= 3UL)
644 {
645 clkSel = CLKCTL1->FLEXCOMM[id].FRGCLKSEL & CLKCTL1_FRGCLKSEL_SEL_MASK;
646 frgMul = ((CLKCTL1->FLEXCOMM[id].FRGCTL) & CLKCTL1_FRGCTL_MULT_MASK) >> CLKCTL1_FRGCTL_MULT_SHIFT;
647 frgDiv = ((CLKCTL1->FLEXCOMM[id].FRGCTL) & CLKCTL1_FRGCTL_DIV_MASK) >> CLKCTL1_FRGCTL_DIV_SHIFT;
648 }
649 else if (id == 14UL)
650 {
651 clkSel = CLKCTL1->FRG14CLKSEL & CLKCTL1_FRG14CLKSEL_SEL_MASK;
652 frgMul = ((CLKCTL1->FRG14CTL) & CLKCTL1_FRGCTL_MULT_MASK) >> CLKCTL1_FRGCTL_MULT_SHIFT;
653 frgDiv = ((CLKCTL1->FRG14CTL) & CLKCTL1_FRGCTL_DIV_MASK) >> CLKCTL1_FRGCTL_DIV_SHIFT;
654 }
655 else
656 {
657 assert(false);
658 }
659
660 switch (clkSel)
661 {
662 case CLKCTL1_FRGCLKSEL_SEL(0):
663 freq = CLOCK_GetMainClkFreq();
664 break;
665
666 case CLKCTL1_FRGCLKSEL_SEL(1):
667 frgPllDiv = (CLKCTL1->FRGPLLCLKDIV & CLKCTL1_FRGPLLCLKDIV_DIV_MASK) + 1U;
668 freq = CLOCK_GetMainPllClkFreq() / frgPllDiv;
669 break;
670
671 case CLKCTL1_FRGCLKSEL_SEL(2):
672 freq = CLOCK_GetSFroFreq();
673 break;
674
675 case CLKCTL1_FRGCLKSEL_SEL(3):
676 freq = CLOCK_GetFFroFreq();
677 break;
678
679 default:
680 freq = 0U;
681 break;
682 }
683
684 return (uint32_t)(((uint64_t)freq * ((uint64_t)frgDiv + 1ULL)) / (frgMul + frgDiv + 1UL));
685 }
686
687 /* Set FRG Clk */
688 /*! @brief Set output of the Fractional baud rate generator
689 * @param config : Configuration to set to FRGn clock.
690 */
CLOCK_SetFRGClock(const clock_frg_clk_config_t * config)691 void CLOCK_SetFRGClock(const clock_frg_clk_config_t *config)
692 {
693 uint32_t i = config->num;
694
695 assert(i <= 14U);
696 assert(config->divider == 255U); /* Always set to 0xFF to use with the fractional baudrate generator.*/
697
698 if (i <= 3UL)
699 {
700 CLKCTL1->FLEXCOMM[i].FRGCLKSEL = (uint32_t)config->sfg_clock_src;
701 CLKCTL1->FLEXCOMM[i].FRGCTL = (CLKCTL1_FRGCTL_MULT(config->mult) | CLKCTL1_FRGCTL_DIV(config->divider));
702 }
703 else if (i == 14UL)
704 {
705 CLKCTL1->FRG14CLKSEL = (uint32_t)config->sfg_clock_src;
706 CLKCTL1->FRG14CTL = (CLKCTL1_FRGCTL_MULT(config->mult) | CLKCTL1_FRGCTL_DIV(config->divider));
707 }
708 else
709 {
710 assert(false);
711 }
712 }
713
714 /*! @brief Return Frequency of DMIC clk
715 * @return Frequency of DMIC clk
716 */
CLOCK_GetDmicClkFreq(void)717 uint32_t CLOCK_GetDmicClkFreq(void)
718 {
719 uint32_t freq = 0U;
720
721 switch ((CLKCTL1->DMIC0FCLKSEL) & CLKCTL1_DMIC0FCLKSEL_SEL_MASK)
722 {
723 case CLKCTL1_DMIC0FCLKSEL_SEL(0):
724 freq = CLOCK_GetSFroFreq();
725 break;
726
727 case CLKCTL1_DMIC0FCLKSEL_SEL(1):
728 freq = CLOCK_GetFFroFreq();
729 break;
730
731 case CLKCTL1_DMIC0FCLKSEL_SEL(2):
732 freq = CLOCK_GetAudioPllClkFreq();
733 break;
734
735 case CLKCTL1_DMIC0FCLKSEL_SEL(3):
736 freq = CLOCK_GetMclkInClkFreq();
737 break;
738
739 case CLKCTL1_DMIC0FCLKSEL_SEL(4):
740 freq = CLOCK_GetLpOscFreq();
741 break;
742
743 case CLKCTL1_DMIC0FCLKSEL_SEL(5):
744 freq = CLOCK_GetClk32KFreq();
745 break;
746
747 case CLKCTL1_DMIC0FCLKSEL_SEL(6):
748 freq = CLOCK_GetMainClkFreq();
749 break;
750
751 default:
752 freq = 0U;
753 break;
754 }
755
756 return freq / ((CLKCTL1->DMIC0CLKDIV & CLKCTL1_DMIC0CLKDIV_DIV_MASK) + 1U);
757 }
758
759 /*! @brief Return Frequency of LCD clk
760 * @return Frequency of LCD clk
761 */
CLOCK_GetLcdClkFreq(void)762 uint32_t CLOCK_GetLcdClkFreq(void)
763 {
764 uint32_t freq = 0U;
765
766 switch ((CLKCTL0->LCDFCLKSEL) & CLKCTL0_LCDFCLKSEL_SEL_MASK)
767 {
768 case CLKCTL0_LCDFCLKSEL_SEL(0):
769 freq = CLOCK_GetMainClkFreq();
770 break;
771
772 case CLKCTL0_LCDFCLKSEL_SEL(1):
773 freq = CLOCK_GetT3PllMciFlexspiClkFreq();
774 break;
775
776 case CLKCTL0_LCDFCLKSEL_SEL(2):
777 freq = CLOCK_GetTcpuMciFlexspiClkFreq();
778 break;
779
780 case CLKCTL0_LCDFCLKSEL_SEL(3):
781 freq = CLOCK_GetTddrMciFlexspiClkFreq();
782 break;
783
784 default:
785 freq = 0U;
786 break;
787 }
788
789 return freq / ((CLKCTL0->LCDFCLKDIV & CLKCTL0_LCDFCLKDIV_DIV_MASK) + 1U);
790 }
791
792 /*! @brief Return Frequency of WDT clk
793 * @return Frequency of WDT clk
794 */
CLOCK_GetWdtClkFreq(void)795 uint32_t CLOCK_GetWdtClkFreq(void)
796 {
797 uint32_t freq = 0U;
798
799 switch ((CLKCTL0->WDT0FCLKSEL) & CLKCTL0_WDT0FCLKSEL_SEL_MASK)
800 {
801 case CLKCTL0_WDT0FCLKSEL_SEL(0):
802 freq = CLOCK_GetLpOscFreq();
803 break;
804
805 case CLKCTL0_WDT0FCLKSEL_SEL(1):
806 freq = CLOCK_GetMainClkFreq();
807 break;
808
809 default:
810 freq = 0U;
811 break;
812 }
813
814 return freq;
815 }
816
817 /*! @brief Return Frequency of mclk
818 * @return Frequency of mclk clk
819 */
CLOCK_GetMclkClkFreq(void)820 uint32_t CLOCK_GetMclkClkFreq(void)
821 {
822 uint32_t freq = 0U;
823
824 switch ((CLKCTL1->AUDIOMCLKSEL) & CLKCTL1_AUDIOMCLKSEL_SEL_MASK)
825 {
826 case CLKCTL1_AUDIOMCLKSEL_SEL(0):
827 freq = CLOCK_GetFFroFreq();
828 break;
829 case CLKCTL1_AUDIOMCLKSEL_SEL(1):
830 freq = CLOCK_GetAudioPllClkFreq();
831 break;
832 case CLKCTL1_AUDIOMCLKSEL_SEL(2):
833 freq = CLOCK_GetMainClkFreq();
834 break;
835 default:
836 freq = 0U;
837 break;
838 }
839 return freq / ((CLKCTL1->AUDIOMCLKDIV & CLKCTL1_AUDIOMCLKDIV_DIV_MASK) + 1U);
840 }
841
842 /*! @brief Return Frequency of sct
843 * @return Frequency of sct clk
844 */
CLOCK_GetSctClkFreq(void)845 uint32_t CLOCK_GetSctClkFreq(void)
846 {
847 uint32_t freq = 0U;
848
849 switch ((CLKCTL0->SCTFCLKSEL) & CLKCTL0_SCTFCLKSEL_SEL_MASK)
850 {
851 case CLKCTL0_SCTFCLKSEL_SEL(0):
852 freq = CLOCK_GetMainClkFreq();
853 break;
854
855 case CLKCTL0_SCTFCLKSEL_SEL(1):
856 freq = CLOCK_GetMainPllClkFreq();
857 break;
858
859 case CLKCTL0_SCTFCLKSEL_SEL(2):
860 freq = CLOCK_GetAux0PllClkFreq();
861 break;
862
863 case CLKCTL0_SCTFCLKSEL_SEL(3):
864 freq = CLOCK_GetFFroFreq();
865 break;
866
867 case CLKCTL0_SCTFCLKSEL_SEL(4):
868 freq = CLOCK_GetAux1PllClkFreq();
869 break;
870
871 case CLKCTL0_SCTFCLKSEL_SEL(5):
872 freq = CLOCK_GetAudioPllClkFreq();
873 break;
874
875 default:
876 freq = 0U;
877 break;
878 }
879
880 return freq / ((CLKCTL0->SCTFCLKDIV & CLKCTL0_SCTFCLKDIV_DIV_MASK) + 1U);
881 }
882
883 /*! @brief Return Frequency of Flexcomm functional Clock
884 * @param id : flexcomm index to get frequency.
885 * @return Frequency of Flexcomm functional Clock
886 */
CLOCK_GetFlexCommClkFreq(uint32_t id)887 uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
888 {
889 uint32_t freq = 0U;
890 uint32_t clkSel = 0U;
891
892 if (id <= 3UL)
893 {
894 clkSel = CLKCTL1->FLEXCOMM[id].FCFCLKSEL;
895 }
896 else if (id == 14UL)
897 {
898 clkSel = CLKCTL1->FC14FCLKSEL;
899 }
900 else
901 {
902 assert(false);
903 }
904
905 switch (clkSel)
906 {
907 case CLKCTL1_FCFCLKSEL_SEL(0):
908 freq = CLOCK_GetSFroFreq();
909 break;
910
911 case CLKCTL1_FCFCLKSEL_SEL(1):
912 freq = CLOCK_GetFFroFreq();
913 break;
914
915 case CLKCTL1_FCFCLKSEL_SEL(2):
916 freq = CLOCK_GetAudioPllClkFreq();
917 break;
918
919 case CLKCTL1_FCFCLKSEL_SEL(3):
920 freq = CLOCK_GetMclkInClkFreq();
921 break;
922
923 case CLKCTL1_FCFCLKSEL_SEL(4):
924 freq = CLOCK_GetFRGClock(id);
925 break;
926
927 default:
928 freq = 0U;
929 break;
930 }
931
932 return freq;
933 }
934
935 /*! @brief Return Frequency of CTimer Clock
936 * @param id : ctimer index to get frequency.
937 * @return Frequency of CTimer Clock
938 */
CLOCK_GetCTimerClkFreq(uint32_t id)939 uint32_t CLOCK_GetCTimerClkFreq(uint32_t id)
940 {
941 uint32_t freq = 0U;
942
943 assert(id < 4U);
944
945 switch ((CLKCTL1->CT32BITFCLKSEL[id]) & CLKCTL1_CT32BITFCLKSEL_SEL_MASK)
946 {
947 case CLKCTL1_CT32BITFCLKSEL_SEL(0):
948 freq = CLOCK_GetMainClkFreq();
949 break;
950
951 case CLKCTL1_CT32BITFCLKSEL_SEL(1):
952 freq = CLOCK_GetSFroFreq();
953 break;
954
955 case CLKCTL1_CT32BITFCLKSEL_SEL(2):
956 freq = CLOCK_GetFFroFreq();
957 break;
958
959 case CLKCTL1_CT32BITFCLKSEL_SEL(3):
960 freq = CLOCK_GetAudioPllClkFreq();
961 break;
962
963 case CLKCTL1_CT32BITFCLKSEL_SEL(4):
964 freq = CLOCK_GetMclkInClkFreq();
965 break;
966
967 case CLKCTL1_CT32BITFCLKSEL_SEL(5):
968 freq = CLOCK_GetLpOscFreq();
969 break;
970
971 default:
972 freq = 0U;
973 break;
974 }
975
976 return freq;
977 }
978
979 /*! @brief Return Frequency of Utick Clock
980 * @return Frequency of Utick Clock
981 */
CLOCK_GetUtickClkFreq(void)982 uint32_t CLOCK_GetUtickClkFreq(void)
983 {
984 uint32_t freq = 0U;
985
986 switch ((CLKCTL0->UTICKFCLKSEL) & CLKCTL0_UTICKFCLKSEL_SEL_MASK)
987 {
988 case CLKCTL0_UTICKFCLKSEL_SEL(0):
989 freq = CLOCK_GetLpOscFreq();
990 break;
991
992 case CLKCTL1_CT32BITFCLKSEL_SEL(1):
993 freq = CLOCK_GetMainClkFreq();
994 break;
995
996 default:
997 freq = 0U;
998 break;
999 }
1000
1001 return freq;
1002 }
1003
1004 /*! @brief Return Frequency of FLEXSPI Clock
1005 * @return Frequency of FLEXSPI.
1006 */
CLOCK_GetFlexspiClkFreq(void)1007 uint32_t CLOCK_GetFlexspiClkFreq(void)
1008 {
1009 uint32_t freq = 0U;
1010
1011 switch ((CLKCTL0->FLEXSPIFCLKSEL) & CLKCTL0_FLEXSPIFCLKSEL_SEL_MASK)
1012 {
1013 case CLKCTL0_FLEXSPIFCLKSEL_SEL(0):
1014 freq = CLOCK_GetMainClkFreq();
1015 break;
1016
1017 case CLKCTL0_FLEXSPIFCLKSEL_SEL(1):
1018 freq = CLOCK_GetT3PllMciFlexspiClkFreq();
1019 break;
1020
1021 case CLKCTL0_FLEXSPIFCLKSEL_SEL(2):
1022 freq = CLOCK_GetAux0PllClkFreq();
1023 break;
1024
1025 case CLKCTL0_FLEXSPIFCLKSEL_SEL(3):
1026 freq = CLOCK_GetFFroFreq();
1027 break;
1028
1029 case CLKCTL0_FLEXSPIFCLKSEL_SEL(4):
1030 freq = CLOCK_GetAux1PllClkFreq();
1031 break;
1032
1033 case CLKCTL0_FLEXSPIFCLKSEL_SEL(5):
1034 freq = CLOCK_GetTddrMciFlexspiClkFreq();
1035 break;
1036
1037 case CLKCTL0_FLEXSPIFCLKSEL_SEL(6):
1038 freq = CLOCK_GetT3PllMci256mClkFreq();
1039 break;
1040
1041 default:
1042 freq = 0U;
1043 break;
1044 }
1045
1046 return freq / ((CLKCTL0->FLEXSPIFCLKDIV & CLKCTL0_FLEXSPIFCLKDIV_DIV_MASK) + 1U);
1047 }
1048
1049 /*! @brief Return Frequency of USIM Clock
1050 * @return Frequency of USIM.
1051 */
CLOCK_GetUsimClkFreq(void)1052 uint32_t CLOCK_GetUsimClkFreq(void)
1053 {
1054 uint32_t freq = 0U;
1055
1056 switch ((CLKCTL0->USIMFCLKSEL) & CLKCTL0_USIMFCLKSEL_SEL_MASK)
1057 {
1058 case CLKCTL0_USIMFCLKSEL_SEL(0):
1059 freq = CLOCK_GetMainClkFreq();
1060 break;
1061
1062 case CLKCTL0_USIMFCLKSEL_SEL(1):
1063 freq = CLOCK_GetAudioPllClkFreq();
1064 break;
1065
1066 case CLKCTL0_USIMFCLKSEL_SEL(2):
1067 freq = CLOCK_GetFFroFreq();
1068 break;
1069
1070 default:
1071 freq = 0U;
1072 break;
1073 }
1074
1075 return freq / ((CLKCTL0->USIMFCLKDIV & CLKCTL0_USIMFCLKDIV_DIV_MASK) + 1U);
1076 }
1077
1078 /*! @brief Return Frequency of GAU Clock
1079 * @return Frequency of GAU.
1080 */
CLOCK_GetGauClkFreq(void)1081 uint32_t CLOCK_GetGauClkFreq(void)
1082 {
1083 uint32_t freq = 0U;
1084
1085 switch ((CLKCTL0->GAUFCLKSEL) & CLKCTL0_GAUFCLKSEL_SEL_MASK)
1086 {
1087 case CLKCTL0_GAUFCLKSEL_SEL(0):
1088 freq = CLOCK_GetMainClkFreq();
1089 break;
1090
1091 case CLKCTL0_GAUFCLKSEL_SEL(1):
1092 freq = CLOCK_GetT3PllMci256mClkFreq();
1093 break;
1094
1095 case CLKCTL0_GAUFCLKSEL_SEL(2):
1096 freq = CLOCK_GetAvPllCh2Freq();
1097 break;
1098
1099 default:
1100 freq = 0U;
1101 break;
1102 }
1103
1104 return freq / ((CLKCTL0->GAUFCLKDIV & CLKCTL0_GAUFCLKDIV_DIV_MASK) + 1U);
1105 }
1106
1107 /*! @brief Return Frequency of OSTimer Clock
1108 * @return Frequency of OSTimer.
1109 */
CLOCK_GetOSTimerClkFreq(void)1110 uint32_t CLOCK_GetOSTimerClkFreq(void)
1111 {
1112 uint32_t freq = 0U;
1113
1114 switch ((CLKCTL1->OSEVENTFCLKSEL) & CLKCTL1_OSEVENTFCLKSEL_SEL_MASK)
1115 {
1116 case CLKCTL1_OSEVENTFCLKSEL_SEL(0):
1117 freq = CLOCK_GetLpOscFreq();
1118 break;
1119
1120 case CLKCTL1_OSEVENTFCLKSEL_SEL(1):
1121 freq = CLOCK_GetClk32KFreq();
1122 break;
1123
1124 case CLKCTL1_OSEVENTFCLKSEL_SEL(2):
1125 freq = CLOCK_GetCoreSysClkFreq();
1126 break;
1127
1128 case CLKCTL1_OSEVENTFCLKSEL_SEL(3):
1129 freq = CLOCK_GetMainClkFreq();
1130 break;
1131
1132 default:
1133 freq = 0U;
1134 break;
1135 }
1136
1137 return freq;
1138 }
1139
1140 /*! @brief Enables and disables 32kHz XTAL
1141 * @param enable : true to enable 32k XTAL clock, false to disable clock
1142 */
CLOCK_EnableXtal32K(bool enable)1143 void CLOCK_EnableXtal32K(bool enable)
1144 {
1145 if (enable)
1146 {
1147 AON_SOC_CIU->PAD_PU_PD_EN1 &=
1148 ~(AON_SOC_CIU_PAD_PU_PD_EN1_GPIO22_PU_PD_EN_MASK | AON_SOC_CIU_PAD_PU_PD_EN1_GPIO23_PU_PD_EN_MASK);
1149 AON_SOC_CIU->MCI_IOMUX_EN0 |= (3UL << 22);
1150 PMU->XTAL32K_CTRL |= PMU_XTAL32K_CTRL_X32K_EN_MASK;
1151 while ((PMU->XTAL32K_CTRL & PMU_XTAL32K_CTRL_X32K_RDY_MASK) == 0U)
1152 {
1153 }
1154 }
1155 else
1156 {
1157 PMU->XTAL32K_CTRL &= ~PMU_XTAL32K_CTRL_X32K_EN_MASK;
1158 }
1159 }
1160
1161 /*! @brief Enables and disables RTC 32KHz
1162 * @param enable : true to enable 32k RTC clock, false to disable clock
1163 */
CLOCK_EnableRtc32K(bool enable)1164 void CLOCK_EnableRtc32K(bool enable)
1165 {
1166 if (enable)
1167 {
1168 CLKCTL0->CLK32KHZCTL0 |= CLKCTL0_CLK32KHZCTL0_ENA_32KHZ_MASK;
1169 }
1170 else
1171 {
1172 CLKCTL0->CLK32KHZCTL0 &= ~CLKCTL0_CLK32KHZCTL0_ENA_32KHZ_MASK;
1173 }
1174 }
1175
CLOCK_CfgTcpuRefClk(uint32_t targetHz,clock_tcpu_flexspi_div_t div)1176 static uint32_t CLOCK_CfgTcpuRefClk(uint32_t targetHz, clock_tcpu_flexspi_div_t div)
1177 {
1178 uint32_t freq = 0UL;
1179 uint32_t steps = 0UL;
1180
1181 if (CLK_XTAL_OSC_CLK == CLK_XTAL_OSC_CLK_40000KHZ)
1182 {
1183 /* Fbdiv from 75 to 96, step 40MHz */
1184 freq = MAX(targetHz, CLOCK_MHZ(3000UL));
1185 freq = MIN(freq, CLOCK_MHZ(3840UL));
1186 /* Find the closest freq to target */
1187 steps = (freq + CLOCK_MHZ(20UL) - CLOCK_MHZ(3000UL)) / CLOCK_MHZ(40UL);
1188 freq = CLOCK_MHZ(3000UL) + steps * CLOCK_MHZ(40UL);
1189 /* Get step register value */
1190 steps += 75UL;
1191 }
1192 else if (CLK_XTAL_OSC_CLK == CLK_XTAL_OSC_CLK_38400KHZ)
1193 {
1194 /* Fbdiv from 78 to 100, step 38.4MHz */
1195 freq = MAX(targetHz, CLOCK_KHZ(2995200UL));
1196 freq = MIN(freq, CLOCK_MHZ(3840UL));
1197 /* Find the closest freq to target */
1198 steps = (freq + CLOCK_KHZ(19200UL) - CLOCK_KHZ(2995200UL)) / CLOCK_KHZ(38400UL);
1199 freq = CLOCK_KHZ(2995200UL) + steps * CLOCK_KHZ(38400UL);
1200 /* Get step register value */
1201 steps += 78UL;
1202 }
1203 else
1204 {
1205 assert(false);
1206 }
1207
1208 SYSCTL2->PLL_CTRL =
1209 (SYSCTL2->PLL_CTRL & ~(SYSCTL2_PLL_CTRL_TCPU_FBDIV_MASK | SYSCTL2_PLL_CTRL_TCPU_FLEXSPI_CLK_SEL_MASK)) |
1210 SYSCTL2_PLL_CTRL_TCPU_FBDIV(steps) | SYSCTL2_PLL_CTRL_TCPU_FLEXSPI_CLK_SEL(div);
1211
1212 return freq;
1213 }
1214
1215 /*! @brief Initialize TCPU FVCO to target frequency.
1216 * For 40MHz XTAL, FVCO ranges from 3000MHz to 3840MHz.
1217 For 38.4MHz XTAL, FVCO ranges from 2995.2MHz to 3840MHz
1218 * @param targetHz : Target FVCO frequency in Hz.
1219 * @param div : Divider for tcpu_mci_flexspi_clk.
1220 * @return Actual FVCO frequency in Hz.
1221 */
CLOCK_InitTcpuRefClk(uint32_t targetHz,clock_tcpu_flexspi_div_t div)1222 uint32_t CLOCK_InitTcpuRefClk(uint32_t targetHz, clock_tcpu_flexspi_div_t div)
1223 {
1224 uint32_t freq;
1225
1226 if ((SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_TCPU_PDB_MASK) != 0U)
1227 {
1228 CLOCK_DeinitTcpuRefClk();
1229 }
1230
1231 SYSPLL_TCPU->TCPU_CTRL_ONE_REG = 0x74U;
1232 freq = CLOCK_CfgTcpuRefClk(targetHz, div);
1233
1234 /* Set PDB */
1235 SYSCTL2->PLL_CTRL |= SYSCTL2_PLL_CTRL_TCPU_PDB_MASK;
1236 /* Wait PLL lock */
1237 while ((SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_TCPU_LOCK_MASK) == 0U)
1238 {
1239 }
1240
1241 return freq;
1242 }
1243
1244 /*! brief Deinit the TCPU reference clock.
1245 * param none.
1246 */
CLOCK_DeinitTcpuRefClk(void)1247 void CLOCK_DeinitTcpuRefClk(void)
1248 {
1249 /* Gate all TCPU output clocks */
1250 SYSCTL2->SOURCE_CLK_GATE |=
1251 SYSCTL2_SOURCE_CLK_GATE_TCPU_MCI_CLK_CG_MASK | SYSCTL2_SOURCE_CLK_GATE_TCPU_MCI_FLEXSPI_CLK_CG_MASK;
1252 /* Clear PDB */
1253 SYSCTL2->PLL_CTRL &= ~SYSCTL2_PLL_CTRL_TCPU_PDB_MASK;
1254 /* Wait PLL lock */
1255 /* Ensure SystemCoreClock is up to date for accurate CLOCK_DelayUs() */
1256 SystemCoreClockUpdate();
1257 CLOCK_DelayUs(1U);
1258
1259 CLOCK_DisableClock(kCLOCK_RefClkTcpu);
1260 }
1261
1262 /*! @brief Initialize the TDDR reference clock.
1263 * @param div : Divider for tddr_mci_flexspi_clk.
1264 */
CLOCK_InitTddrRefClk(clock_tddr_flexspi_div_t div)1265 void CLOCK_InitTddrRefClk(clock_tddr_flexspi_div_t div)
1266 {
1267 if ((SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_TDDR_PDB_MASK) != 0U)
1268 {
1269 CLOCK_DeinitTddrRefClk();
1270 }
1271
1272 REG_SYSPLL_TDDR->TDDR_CTRL_ONE_REG = 0x74U;
1273 SYSCTL2->PLL_CTRL =
1274 (SYSCTL2->PLL_CTRL & ~SYSCTL2_PLL_CTRL_TDDR_FLEXSPI_CLK_SEL_MASK) | SYSCTL2_PLL_CTRL_TDDR_FLEXSPI_CLK_SEL(div);
1275
1276 /* Set PDB */
1277 SYSCTL2->PLL_CTRL |= SYSCTL2_PLL_CTRL_TDDR_PDB_MASK;
1278 /* Wait PLL lock */
1279 while ((SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_TDDR_LOCK_MASK) == 0U)
1280 {
1281 }
1282 }
1283
1284 /*! brief Deinit the TDDR reference clock.
1285 * param none.
1286 */
CLOCK_DeinitTddrRefClk(void)1287 void CLOCK_DeinitTddrRefClk(void)
1288 {
1289 /* Gate all TDDR output clocks */
1290 SYSCTL2->SOURCE_CLK_GATE |=
1291 SYSCTL2_SOURCE_CLK_GATE_TDDR_MCI_ENET_CLK_CG_MASK | SYSCTL2_SOURCE_CLK_GATE_TDDR_MCI_FLEXSPI_CLK_CG_MASK;
1292 /* Clear PDB */
1293 SYSCTL2->PLL_CTRL &= ~SYSCTL2_PLL_CTRL_TDDR_PDB_MASK;
1294 /* Wait PLL lock */
1295 /* Ensure SystemCoreClock is up to date for accurate CLOCK_DelayUs() */
1296 SystemCoreClockUpdate();
1297 CLOCK_DelayUs(1U);
1298
1299 CLOCK_DisableClock(kCLOCK_RefClkTddr);
1300 }
1301
1302 /*! @brief Initialize the T3 reference clock.
1303 * @param cnfg : t3pll_mci_48_60m_irc clock configuration
1304 */
CLOCK_InitT3RefClk(clock_t3_mci_irc_config_t cnfg)1305 void CLOCK_InitT3RefClk(clock_t3_mci_irc_config_t cnfg)
1306 {
1307 if ((SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_T3_PDB_MASK) != 0U)
1308 {
1309 CLOCK_DeinitT3RefClk();
1310 }
1311
1312 if (cnfg == kCLOCK_T3MciIrc60m)
1313 {
1314 SYSPLL_T3->CLKTREE_CTRL_SIX_REG = 0x5U;
1315 }
1316 else
1317 {
1318 SYSPLL_T3->CLKTREE_CTRL_SIX_REG = 0xAU;
1319 }
1320 /* Set PDB */
1321 SYSCTL2->PLL_CTRL |= SYSCTL2_PLL_CTRL_T3_PDB_MASK;
1322 /* Wait PLL lock */
1323 while ((SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_T3_LOCK_MASK) == 0U)
1324 {
1325 }
1326 }
1327
1328 /*! brief Deinit the T3 reference clock.
1329 * param none.
1330 */
CLOCK_DeinitT3RefClk(void)1331 void CLOCK_DeinitT3RefClk(void)
1332 {
1333 /* Ensure SystemCoreClock is up to date for accurate CLOCK_DelayUs() */
1334 SystemCoreClockUpdate();
1335 /* Gate all T3 output clocks */
1336 SYSCTL2->SOURCE_CLK_GATE |=
1337 SYSCTL2_SOURCE_CLK_GATE_T3PLL_MCI_48_60M_IRC_CG_MASK | SYSCTL2_SOURCE_CLK_GATE_T3PLL_MCI_256M_CG_MASK |
1338 SYSCTL2_SOURCE_CLK_GATE_T3PLL_MCI_213P3M_CG_MASK | SYSCTL2_SOURCE_CLK_GATE_T3PLL_MCI_FLEXSPI_CLK_CG_MASK;
1339 /* Clear PDB */
1340 SYSCTL2->PLL_CTRL &= ~SYSCTL2_PLL_CTRL_T3_PDB_MASK;
1341
1342 /* Wait PLL lock */
1343 CLOCK_DelayUs(1U);
1344 }
1345
CLOCK_ConfigAvPll(void)1346 static void CLOCK_ConfigAvPll(void)
1347 {
1348 uint32_t fbdiv = 0x51U;
1349 uint32_t freq_offset_c8 = 0x0U;
1350 uint32_t pll_calclk_div = 0x14U;
1351 uint32_t refdiv = 0x2U;
1352 uint32_t ext_speed = 0x2U;
1353 uint32_t intpi = 0x3U;
1354 uint32_t intpr = 0x4U;
1355 uint32_t icp = 0x5U;
1356
1357 if (CLK_XTAL_OSC_CLK == CLK_XTAL_OSC_CLK_38400KHZ)
1358 {
1359 fbdiv = 0x54U;
1360 freq_offset_c8 = 0x4924U;
1361 pll_calclk_div = 0x13U;
1362 }
1363
1364 SYSCTL2->AVPLL_CTRL2 =
1365 (SYSCTL2->AVPLL_CTRL2 & ~(SYSCTL2_AVPLL_CTRL2_ICP_MASK | SYSCTL2_AVPLL_CTRL2_INTPI_MASK |
1366 SYSCTL2_AVPLL_CTRL2_INTPR_MASK | SYSCTL2_AVPLL_CTRL2_PLL_CALCLK_DIV_MASK)) |
1367 SYSCTL2_AVPLL_CTRL2_ICP(icp) | SYSCTL2_AVPLL_CTRL2_INTPI(intpi) | SYSCTL2_AVPLL_CTRL2_INTPR(intpr) |
1368 SYSCTL2_AVPLL_CTRL2_PLL_CALCLK_DIV(pll_calclk_div);
1369
1370 SYSCTL2->AVPLL_CTRL3 =
1371 (SYSCTL2->AVPLL_CTRL3 & ~SYSCTL2_AVPLL_CTRL3_REFDIV_MASK) | SYSCTL2_AVPLL_CTRL3_REFDIV(refdiv);
1372
1373 SYSCTL2->AVPLL_CTRL0 =
1374 (SYSCTL2->AVPLL_CTRL0 & ~SYSCTL2_AVPLL_CTRL0_EXT_SPEED_MASK) | SYSCTL2_AVPLL_CTRL0_EXT_SPEED(ext_speed);
1375
1376 SYSCTL2->AVPLL_CTRL1 = (SYSCTL2->AVPLL_CTRL1 & ~SYSCTL2_AVPLL_CTRL1_FBDIV_MASK) | SYSCTL2_AVPLL_CTRL1_FBDIV(fbdiv);
1377
1378 SYSCTL2->AVPLL_CTRL8 =
1379 (SYSCTL2->AVPLL_CTRL8 & ~(SYSCTL2_AVPLL_CTRL8_EN_LP_C8_MASK | SYSCTL2_AVPLL_CTRL8_FREQ_OFFSET_C8_MASK)) |
1380 SYSCTL2_AVPLL_CTRL8_FREQ_OFFSET_C8(freq_offset_c8);
1381 }
1382
CLOCK_ConfigAvPllCh1(clock_avpll_ch_freq_t ch1Freq)1383 static void CLOCK_ConfigAvPllCh1(clock_avpll_ch_freq_t ch1Freq)
1384 {
1385 if (ch1Freq != kCLOCK_AvPllChUnchanged)
1386 {
1387 SYSCTL2->AVPLL_CTRL2 = (SYSCTL2->AVPLL_CTRL2 & ~SYSCTL2_AVPLL_CTRL2_POSTDIV_0P5_C1_MASK) |
1388 SYSCTL2_AVPLL_CTRL2_POSTDIV_0P5_C1(s_avpllPostDiv0p5[(uint32_t)ch1Freq]);
1389
1390 SYSCTL2->AVPLL_CTRL1 = (SYSCTL2->AVPLL_CTRL1 & ~SYSCTL2_AVPLL_CTRL1_FREQ_OFFSET_C1_MASK) |
1391 SYSCTL2_AVPLL_CTRL1_FREQ_OFFSET_C1(s_avpllFreqOff[(uint32_t)ch1Freq]);
1392
1393 SYSCTL2->AVPLL_CTRL5 = (SYSCTL2->AVPLL_CTRL5 & ~SYSCTL2_AVPLL_CTRL5_POSTDIV_C1_MASK) |
1394 SYSCTL2_AVPLL_CTRL5_POSTDIV_C1(s_avpllPostDiv[(uint32_t)ch1Freq]);
1395 }
1396 }
1397
CLOCK_ConfigAvPllCh2(clock_avpll_ch_freq_t ch2Freq)1398 static void CLOCK_ConfigAvPllCh2(clock_avpll_ch_freq_t ch2Freq)
1399 {
1400 if (ch2Freq != kCLOCK_AvPllChUnchanged)
1401 {
1402 SYSCTL2->AVPLL_CTRL12 = (SYSCTL2->AVPLL_CTRL12 & ~SYSCTL2_AVPLL_CTRL12_POSTDIV_0P5_C2_MASK) |
1403 SYSCTL2_AVPLL_CTRL12_POSTDIV_0P5_C2(s_avpllPostDiv0p5[(uint32_t)ch2Freq]);
1404
1405 SYSCTL2->AVPLL_CTRL11 = SYSCTL2_AVPLL_CTRL11_FREQ_OFFSET_C2(s_avpllFreqOff[(uint32_t)ch2Freq]) |
1406 SYSCTL2_AVPLL_CTRL11_POSTDIV_C2(s_avpllPostDiv[(uint32_t)ch2Freq]);
1407 }
1408 }
1409
CLOCK_PowerUpAnaGrp(void)1410 static void CLOCK_PowerUpAnaGrp(void)
1411 {
1412 uint32_t anaGrpPu = SYSCTL2->ANA_GRP_CTRL;
1413
1414 if ((anaGrpPu & SYSCTL2_ANA_GRP_CTRL_PU_AG_MASK) == 0U)
1415 {
1416 SYSCTL2->ANA_GRP_CTRL = anaGrpPu | SYSCTL2_ANA_GRP_CTRL_PU_AG_MASK;
1417 CLOCK_DelayUs(50U); /* Delay 50us */
1418 }
1419 }
1420
CLOCK_PowerDownAnaGrp(void)1421 static void CLOCK_PowerDownAnaGrp(void)
1422 {
1423 uint32_t anaGrpPu = SYSCTL2->ANA_GRP_CTRL;
1424
1425 if ((anaGrpPu & SYSCTL2_ANA_GRP_CTRL_PU_AG_MASK) != 0U)
1426 {
1427 SYSCTL2->ANA_GRP_CTRL = anaGrpPu & ~SYSCTL2_ANA_GRP_CTRL_PU_AG_MASK;
1428 }
1429 }
1430
1431 /*! @brief Initialize the AVPLL.
1432 * @param enableCh1 : Enable AVPLL channel1
1433 * @param enableCh2 : Enable AVPLL channel2
1434 * @param enableCali : Enable AVPLL calibration
1435 */
CLOCK_EnableAvPllCh(bool enableCh1,bool enableCh2,bool enableCali)1436 void CLOCK_EnableAvPllCh(bool enableCh1, bool enableCh2, bool enableCali)
1437 {
1438 uint32_t calDoneDelay;
1439
1440 /* Step 3: Pull up PU_C1 PU_C2 */
1441 if (enableCh1)
1442 {
1443 SYSCTL2->AVPLL_CTRL2 |= SYSCTL2_AVPLL_CTRL2_PU_C1_MASK;
1444 }
1445 if (enableCh2)
1446 {
1447 SYSCTL2->AVPLL_CTRL12 |= SYSCTL2_AVPLL_CTRL12_PU_C2_MASK;
1448 }
1449
1450 /* Pull up freq_offset_c8_ready */
1451 SYSCTL2->AVPLL_CTRL8 |= SYSCTL2_AVPLL_CTRL8_FREQ_OFFSET_READY_C8_MASK;
1452 CLOCK_DelayUs(3U); /* Delay 516*FVCO*4, about 3us */
1453
1454 /* Step 4: Pull low freq_offset_c8_ready */
1455 SYSCTL2->AVPLL_CTRL8 &= ~SYSCTL2_AVPLL_CTRL8_FREQ_OFFSET_READY_C8_MASK;
1456 CLOCK_DelayUs(2U); /* Delay more than 1us, recommended to delay 2us */
1457
1458 /* Step 5: Pull low RESET_C8 */
1459 SYSCTL2->AVPLL_CTRL8 &= ~SYSCTL2_AVPLL_CTRL8_AVPLL_RESET_C8_MASK;
1460 CLOCK_DelayUs(5U); /* Delay 5us. */
1461
1462 if (enableCali)
1463 {
1464 /* Step 6: Cali start */
1465 SYSCTL2->AVPLL_CTRL2 |= SYSCTL2_AVPLL_CTRL2_PLL_CAL_START_MASK;
1466 }
1467 CLOCK_DelayUs(5U); /* Delay 5us */
1468
1469 /* Step 7: Pull low RESET_C1 RESET_C2 */
1470 if (enableCh1)
1471 {
1472 SYSCTL2->AVPLL_CTRL8 &= ~SYSCTL2_AVPLL_CTRL8_AVPLL_RESET_C1_MASK;
1473 }
1474 if (enableCh2)
1475 {
1476 SYSCTL2->AVPLL_CTRL13 &= ~SYSCTL2_AVPLL_CTRL13_AVPLL_RESET_C2_MASK;
1477 }
1478 CLOCK_DelayUs(2U); /* Delay 516*FVCO , about 2us */
1479
1480 /* Step 8: Pull high freq_offset_ready_c1/c2 */
1481 if (enableCh1)
1482 {
1483 SYSCTL2->AVPLL_CTRL1 |= SYSCTL2_AVPLL_CTRL1_FREQ_OFFSET_READY_C1_MASK;
1484 }
1485 if (enableCh2)
1486 {
1487 SYSCTL2->AVPLL_CTRL12 |= SYSCTL2_AVPLL_CTRL12_FREQ_OFFSET_READY_C2_MASK;
1488 }
1489 CLOCK_DelayUs(2U); /* Delay 516*FVCO , about 2us */
1490
1491 /* Step 9: pull low freq_offset_ready_c1/2 */
1492 if (enableCh1)
1493 {
1494 SYSCTL2->AVPLL_CTRL1 &= ~SYSCTL2_AVPLL_CTRL1_FREQ_OFFSET_READY_C1_MASK;
1495 }
1496 if (enableCh2)
1497 {
1498 SYSCTL2->AVPLL_CTRL12 &= ~SYSCTL2_AVPLL_CTRL12_FREQ_OFFSET_READY_C2_MASK;
1499 }
1500 CLOCK_DelayUs(12U); /* Delay more than 10us, recommended 12 us */
1501
1502 if (enableCali)
1503 {
1504 /* Step 10: wait cali done */
1505 calDoneDelay = 0U;
1506 while (
1507 ((SYSCTL2->AVPLL_CTRL7 & SYSCTL2_AVPLL_CTRL7_PLL_CAL_DONE_MASK) != SYSCTL2_AVPLL_CTRL7_PLL_CAL_DONE_MASK) &&
1508 (calDoneDelay < 600U)) /* Wait cali done or 600us */
1509 {
1510 calDoneDelay += 10U;
1511 CLOCK_DelayUs(10U);
1512 }
1513 CLOCK_DelayUs(10U);
1514
1515 /* Step 11: clear cali start */
1516 SYSCTL2->AVPLL_CTRL2 &= ~SYSCTL2_AVPLL_CTRL2_PLL_CAL_START_MASK;
1517 }
1518 }
1519
1520 /*! @brief Disable the AVPLL.
1521 * @param disableCh1 : Disable AVPLL channel1, channel unchanged on false.
1522 * @param disableCh2 : Disable AVPLL channel2, channel unchanged on false.
1523 */
CLOCK_DisableAvPllCh(bool disableCh1,bool disableCh2)1524 void CLOCK_DisableAvPllCh(bool disableCh1, bool disableCh2)
1525 {
1526 if (disableCh1)
1527 {
1528 /* Pull up RESET_C1 */
1529 SYSCTL2->AVPLL_CTRL8 |= SYSCTL2_AVPLL_CTRL8_AVPLL_RESET_C1_MASK;
1530 /* Pull low PU_C1 */
1531 SYSCTL2->AVPLL_CTRL2 &= ~SYSCTL2_AVPLL_CTRL2_PU_C1_MASK;
1532 }
1533
1534 if (disableCh2)
1535 {
1536 /* Pull up RESET_C2 */
1537 SYSCTL2->AVPLL_CTRL13 |= SYSCTL2_AVPLL_CTRL13_AVPLL_RESET_C2_MASK;
1538 /* Pull low PU_C2 */
1539 SYSCTL2->AVPLL_CTRL12 &= ~SYSCTL2_AVPLL_CTRL12_PU_C2_MASK;
1540 }
1541 }
1542
1543 /*! @brief Initialize the AVPLL.
1544 * @param cnfg : AVPLL clock configuration
1545 */
CLOCK_InitAvPll(const clock_avpll_config_t * cnfg)1546 void CLOCK_InitAvPll(const clock_avpll_config_t *cnfg)
1547 {
1548 assert(cnfg);
1549
1550 if ((SYSCTL2->AVPLL_CTRL2 & SYSCTL2_AVPLL_CTRL2_PU_MASK) != 0U)
1551 {
1552 /* Pull down AVPLL power for initialization. */
1553 CLOCK_DeinitAvPll();
1554 }
1555
1556 /* Ensure SystemCoreClock is up to date for accurate CLOCK_DelayUs() */
1557 SystemCoreClockUpdate();
1558
1559 /* Ensure ANA_GRP is powered up */
1560 CLOCK_PowerUpAnaGrp();
1561
1562 /* Configure CH1/CH2 frequency */
1563 CLOCK_ConfigAvPll();
1564 CLOCK_ConfigAvPllCh1(cnfg->ch1Freq);
1565 CLOCK_ConfigAvPllCh2(cnfg->ch2Freq);
1566
1567 /* Step 1: Pull up PU */
1568 SYSCTL2->AVPLL_CTRL2 |= SYSCTL2_AVPLL_CTRL2_PU_MASK;
1569 CLOCK_DelayUs(15U); /* Wait more than 10us, recommended to delay 15us */
1570
1571 /* Step 2: Pull low RESET */
1572 SYSCTL2->AVPLL_CTRL8 &= ~SYSCTL2_AVPLL_CTRL8_AVPLL_RESET_MASK;
1573 CLOCK_DelayUs(15U); /* Wait more than 10us, recommended to delay 15us */
1574
1575 /* Enable channels */
1576 CLOCK_EnableAvPllCh(true, true, cnfg->enableCali);
1577 }
1578
1579 /*! @brief Deinit the AVPLL.
1580 */
CLOCK_DeinitAvPll(void)1581 void CLOCK_DeinitAvPll(void)
1582 {
1583 CLOCK_DisableAvPllCh(true, true);
1584
1585 /* Pull up RESET */
1586 SYSCTL2->AVPLL_CTRL8 |= SYSCTL2_AVPLL_CTRL8_AVPLL_RESET_MASK;
1587 /* Pull up RESET_C8 */
1588 SYSCTL2->AVPLL_CTRL8 |= SYSCTL2_AVPLL_CTRL8_AVPLL_RESET_C8_MASK;
1589 /* Pull low PU */
1590 SYSCTL2->AVPLL_CTRL2 &= ~SYSCTL2_AVPLL_CTRL2_PU_MASK;
1591
1592 /* Disable REFCLK AUD. */
1593 CLOCK_DisableClock(kCLOCK_RefClkAud);
1594
1595 if ((SYSCTL2->USB_CTRL & SYSCTL2_USB_CTRL_USB_PU_MASK) == 0U)
1596 {
1597 /* USB also not used, ANA_GRP can be powered down. */
1598 CLOCK_PowerDownAnaGrp();
1599 }
1600 }
1601
1602 /*! @brief Update the AVPLL channel configuration. Enable/Disable state keeps unchanged.
1603 * @param ch1Freq : Channel 1 frequency to set.
1604 * @param ch2Freq : Channel 2 frequency to set.
1605 * @param enableCali : Enable AVPLL calibration.
1606 */
CLOCK_ConfigAvPllCh(clock_avpll_ch_freq_t ch1Freq,clock_avpll_ch_freq_t ch2Freq,bool enableCali)1607 void CLOCK_ConfigAvPllCh(clock_avpll_ch_freq_t ch1Freq, clock_avpll_ch_freq_t ch2Freq, bool enableCali)
1608 {
1609 bool needRenableCh1, needRenableCh2;
1610
1611 if ((ch1Freq == kCLOCK_AvPllChUnchanged) && (ch2Freq == kCLOCK_AvPllChUnchanged))
1612 {
1613 /* Nothing to change. */
1614 return;
1615 }
1616
1617 /* If channel enabled and need to update configuration, need to reenable. */
1618 needRenableCh1 =
1619 ((SYSCTL2->AVPLL_CTRL2 & SYSCTL2_AVPLL_CTRL2_PU_C1_MASK) != 0U) && (ch1Freq != kCLOCK_AvPllChUnchanged);
1620 needRenableCh2 =
1621 ((SYSCTL2->AVPLL_CTRL12 & SYSCTL2_AVPLL_CTRL12_PU_C2_MASK) != 0U) && (ch2Freq != kCLOCK_AvPllChUnchanged);
1622
1623 /* Disable channel before update configuration. */
1624 CLOCK_DisableAvPllCh(needRenableCh1, needRenableCh2);
1625
1626 CLOCK_ConfigAvPll();
1627
1628 if (ch1Freq != kCLOCK_AvPllChUnchanged)
1629 {
1630 CLOCK_ConfigAvPllCh1(ch1Freq);
1631 }
1632 if (ch2Freq != kCLOCK_AvPllChUnchanged)
1633 {
1634 CLOCK_ConfigAvPllCh2(ch2Freq);
1635 }
1636
1637 /* Reenable channel if needed. */
1638 CLOCK_EnableAvPllCh(needRenableCh1, needRenableCh2, enableCali);
1639 }
1640
1641 /*! @brief Enable USB HS PHY PLL clock.
1642 *
1643 * This function enables USB HS PHY PLL clock.
1644 */
CLOCK_EnableUsbhsPhyClock(void)1645 void CLOCK_EnableUsbhsPhyClock(void)
1646 {
1647 uint32_t value;
1648 value = SYSCTL2->USB_CTRL;
1649 uint32_t delay = 100000;
1650
1651 /* Ensure SystemCoreClock is up to date for accurate CLOCK_DelayUs() */
1652 SystemCoreClockUpdate();
1653
1654 /* Ensure ANA_GRP is powered on */
1655 SYSCTL2->ANA_GRP_CTRL |= SYSCTL2_ANA_GRP_CTRL_PU_XTL_MASK;
1656 CLOCK_PowerUpAnaGrp();
1657
1658 /* Reset USB PHY */
1659 value |=
1660 SYSCTL2_USB_CTRL_SOFT_PHY_RESET_MASK | SYSCTL2_USB_CTRL_PHY_RESET_SEL_MASK; /* Use soft reset to reset PHY */
1661 SYSCTL2->USB_CTRL =
1662 value & ~(SYSCTL2_USB_CTRL_USB_PU_PLL_MASK | SYSCTL2_USB_CTRL_USB_PU_MASK | SYSCTL2_USB_CTRL_USB_PU_OTG_MASK);
1663 __NOP();
1664 value &= ~(SYSCTL2_USB_CTRL_SOFT_PHY_RESET_MASK |
1665 SYSCTL2_USB_CTRL_PHY_RESET_SEL_MASK); /* It is an active high reset; this bit is inverted */
1666 SYSCTL2->USB_CTRL = value;
1667 /* Power up PHY OTG detection circuit */
1668 USBOTG->PHY_REG_OTG_CONTROL |= USBC_PHY_REG_CHGDTC_CONTRL_1_PD_EN_MASK;
1669 /* Analog power up through pin */
1670 value |= SYSCTL2_USB_CTRL_USB_PU_MASK | SYSCTL2_USB_CTRL_USB_PU_OTG_MASK;
1671 SYSCTL2->USB_CTRL = value;
1672 /* Power up PLL via pin; raising edge will auto trigger calibration */
1673 value |= SYSCTL2_USB_CTRL_USB_PU_PLL_MASK;
1674 SYSCTL2->USB_CTRL = value;
1675 while ((delay-- > 0U) && ((USBOTG->PLL_CONTROL_0 & USBC_PLL_CONTROL_0_PLL_READY_MASK) == 0U))
1676 {
1677 }
1678 }
1679
1680 /*! @brief Disable USB HS PHY PLL clock.
1681 *
1682 * This function disables USB HS PHY PLL clock.
1683 */
CLOCK_DisableUsbhsPhyClock(void)1684 void CLOCK_DisableUsbhsPhyClock(void)
1685 {
1686 uint32_t value;
1687 value = SYSCTL2->USB_CTRL;
1688 /* Power down PHY OTG detection circuit */
1689 USBOTG->PHY_REG_OTG_CONTROL |= USBC_PHY_REG_CHGDTC_CONTRL_1_PD_EN_MASK;
1690 /* Analog power down through pin */
1691 value &= ~SYSCTL2_USB_CTRL_USB_PU_MASK & ~SYSCTL2_USB_CTRL_USB_PU_OTG_MASK;
1692 SYSCTL2->USB_CTRL = value;
1693 /* Power down PLL via pin */
1694 value &= ~SYSCTL2_USB_CTRL_USB_PU_PLL_MASK;
1695 SYSCTL2->USB_CTRL = value;
1696 if ((SYSCTL2->AVPLL_CTRL2 & SYSCTL2_AVPLL_CTRL2_PU_MASK) == 0U)
1697 {
1698 /* AVPLL also not used, ANA_GRP can be powered down. */
1699 CLOCK_PowerDownAnaGrp();
1700 }
1701 SYSCTL2->ANA_GRP_CTRL &= ~SYSCTL2_ANA_GRP_CTRL_PU_XTL_MASK;
1702 }
1703