aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/devices/MCIMX7U3/drivers/fsl_clock.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/MCIMX7U3/drivers/fsl_clock.h')
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MCIMX7U3/drivers/fsl_clock.h1935
1 files changed, 1935 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MCIMX7U3/drivers/fsl_clock.h b/lib/chibios-contrib/ext/mcux-sdk/devices/MCIMX7U3/drivers/fsl_clock.h
new file mode 100644
index 000000000..0a20b67e6
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MCIMX7U3/drivers/fsl_clock.h
@@ -0,0 +1,1935 @@
1/*
2 * Copyright 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019, NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#ifndef _FSL_CLOCK_H_
10#define _FSL_CLOCK_H_
11
12#include "fsl_common.h"
13
14/*! @addtogroup clock */
15/*! @{ */
16
17/*! @file */
18
19/*******************************************************************************
20 * Definitions
21 ******************************************************************************/
22
23/*! @brief Configure whether driver controls clock
24 *
25 * When set to 0, peripheral drivers will enable clock in initialize function
26 * and disable clock in de-initialize function. When set to 1, peripheral
27 * driver will not control the clock, application could control the clock out of
28 * the driver.
29 *
30 * @note All drivers share this feature switcher. If it is set to 1, application
31 * should handle clock enable and disable for all drivers.
32 */
33#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
34#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
35#endif
36
37/*! @name Driver version */
38/*@{*/
39/*! @brief CLOCK driver version 2.3.1. */
40#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 3, 1))
41/*@}*/
42
43/* Definition for delay API in clock driver, users can redefine it to the real application. */
44#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
45#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (192000000UL)
46#endif
47
48/*!
49 * @brief Re-map the SCG peripheral base address for i.MX 7ULP.
50 * This driver is for SCG 0 on Core 0 of i.MX 7ULP only.
51 */
52#define SCG SCG0
53
54/*!
55 * @brief SCG (A/S)PLLPFD[PFDx] value.
56 */
57#define SCG_PLLPFD_PFD_VAL(pfdClkout, fracValue) ((uint32_t)((uint32_t)(fracValue) << (uint32_t)(pfdClkout)))
58/*!
59 * @brief SCG (A/S)PLLPFD[PFD] mask.
60 */
61#define SCG_PLLPFD_PFD_MASK(pfdClkout) ((uint32_t)((uint32_t)(SCG_APLLPFD_PFD0_MASK) << (uint32_t)(pfdClkout)))
62/*!
63 * @brief SCG (A/S)PLLPFD[PFDx_VALID] mask.
64 */
65#define SCG_PLLPFD_PFD_VALID_MASK(pfdClkout) \
66 ((uint32_t)((uint32_t)SCG_APLLPFD_PFD0_VALID_MASK << (uint32_t)(pfdClkout)))
67/*!
68 * @brief SCG (A/S)PLLPFD[PFDx_CLKGATE] mask.
69 */
70#define SCG_PLLPFD_PFD_CLKGATE_MASK(pfdClkout) \
71 ((uint32_t)((uint32_t)SCG_APLLPFD_PFD0_CLKGATE_MASK << (uint32_t)(pfdClkout)))
72
73/*! @brief External XTAL0 (OSC0/SYSOSC) clock frequency.
74 *
75 * The XTAL0/EXTAL0 (OSC0/SYSOSC) clock frequency in Hz. When the clock is set up, use the
76 * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example,
77 * if XTAL0 is 8 MHz:
78 * @code
79 * CLOCK_InitSysOsc(...);
80 * CLOCK_SetXtal0Freq(80000000);
81 * @endcode
82 *
83 * This is important for the multicore platforms where only one core needs to set up the
84 * OSC0/SYSOSC using CLOCK_InitSysOsc. All other cores need to call the CLOCK_SetXtal0Freq
85 * to get a valid clock frequency.
86 */
87extern volatile uint32_t g_xtal0Freq;
88
89/*! @brief External XTAL32/EXTAL32 clock frequency.
90 *
91 * The XTAL32/EXTAL32 clock frequency in Hz. When the clock is set up, use the
92 * function CLOCK_SetXtal32Freq to set the value in the clock driver.
93 *
94 * This is important for the multicore platforms where only one core needs to set up
95 * the clock. All other cores need to call the CLOCK_SetXtal32Freq
96 * to get a valid clock frequency.
97 */
98extern volatile uint32_t g_xtal32Freq;
99
100/*! @brief External LVDS pad clock frequency.
101 *
102 * The LVDS pad clock frequency in Hz. When the clock is set up, use the
103 * function CLOCK_SetLvdsFreq to set the value in the clock driver.
104 *
105 */
106extern volatile uint32_t g_lvdsFreq;
107
108/*!
109 * @brief Re-define PCC register masks and bitfield operations to unify
110 * the different namings in the soc header file.
111 */
112#define PCC_CLKCFG_PCD_MASK (0x7U)
113#define PCC_CLKCFG_PCD_SHIFT (0U)
114#define PCC_CLKCFG_PCD(x) (((uint32_t)(((uint32_t)(x)) << PCC_CLKCFG_PCD_SHIFT)) & PCC_CLKCFG_PCD_MASK)
115#define PCC_CLKCFG_FRAC_MASK (0x8U)
116#define PCC_CLKCFG_FRAC_SHIFT (3U)
117#define PCC_CLKCFG_FRAC(x) (((uint32_t)(((uint32_t)(x)) << PCC_CLKCFG_FRAC_SHIFT)) & PCC_CLKCFG_FRAC_MASK)
118#define PCC_CLKCFG_PCS_MASK (0x7000000U)
119#define PCC_CLKCFG_PCS_SHIFT (24U)
120#define PCC_CLKCFG_PCS(x) (((uint32_t)(((uint32_t)(x)) << PCC_CLKCFG_PCS_SHIFT)) & PCC_CLKCFG_PCS_MASK)
121#define PCC_CLKCFG_INUSE_MASK (0x20000000U)
122#define PCC_CLKCFG_CGC_MASK (0x40000000U)
123#define PCC_CLKCFG_PR_MASK (0x80000000U)
124
125/*! @brief Clock ip name array for DMAMUX. */
126#define DMAMUX_CLOCKS \
127 { \
128 kCLOCK_Dmamux0, kCLOCK_Dmamux1 \
129 }
130
131/*! @brief Clock ip name array for RGPIO2P. */
132#define RGPIO2P_CLOCKS \
133 { \
134 kCLOCK_Rgpio2p0, kCLOCK_Rgpio2p0, kCLOCK_Rgpio2p1, kCLOCK_Rgpio2p1, kCLOCK_Rgpio2p1, kCLOCK_Rgpio2p1 \
135 }
136
137/*! @brief Clock ip name array for SAI. */
138#define SAI_CLOCKS \
139 { \
140 kCLOCK_Sai0, kCLOCK_Sai1 \
141 }
142
143/*! @brief Clock ip name array for PCTL. */
144#define PCTL_CLOCKS \
145 { \
146 kCLOCK_PctlA, kCLOCK_PctlB, kCLOCK_PctlC, kCLOCK_PctlD, kCLOCK_PctlE, kCLOCK_PctlF \
147 }
148
149/*! @brief Clock ip name array for LPI2C. */
150#define LPI2C_CLOCKS \
151 { \
152 kCLOCK_Lpi2c0, kCLOCK_Lpi2c1, kCLOCK_Lpi2c2, kCLOCK_Lpi2c3, kCLOCK_Lpi2c4, kCLOCK_Lpi2c5, kCLOCK_Lpi2c6, \
153 kCLOCK_Lpi2c7 \
154 }
155
156/*! @brief Clock ip name array for FLEXIO. */
157#define FLEXIO_CLOCKS \
158 { \
159 kCLOCK_Flexio0, kCLOCK_Flexio1 \
160 }
161
162/*! @brief Clock ip name array for EDMA. */
163#define EDMA_CLOCKS \
164 { \
165 kCLOCK_Dma0, kCLOCK_Dma1 \
166 }
167
168/*! @brief Clock ip name array for LPUART. */
169#define LPUART_CLOCKS \
170 { \
171 kCLOCK_Lpuart0, kCLOCK_Lpuart1, kCLOCK_Lpuart2, kCLOCK_Lpuart3, kCLOCK_Lpuart4, kCLOCK_Lpuart5, \
172 kCLOCK_Lpuart6, kCLOCK_Lpuart7 \
173 }
174
175/*! @brief Clock ip name array for DAC. */
176#define DAC_CLOCKS \
177 { \
178 kCLOCK_Dac0, kCLOCK_Dac1 \
179 }
180
181/*! @brief Clock ip name array for DAC. */
182#define SNVS_HP_CLOCKS \
183 { \
184 kCLOCK_Snvs \
185 }
186
187#define SNVS_LP_CLOCKS \
188 { \
189 kCLOCK_Snvs \
190 }
191
192/*! @brief Clock ip name array for LPTMR. */
193#define LPTMR_CLOCKS \
194 { \
195 kCLOCK_Lptmr0, kCLOCK_Lptmr1 \
196 }
197
198/*! @brief Clock ip name array for LPADC. */
199#define LPADC_CLOCKS \
200 { \
201 kCLOCK_Adc0, kCLOCK_Adc1 \
202 }
203
204/*! @brief Clock ip name array for TRNG. */
205#define TRNG_CLOCKS \
206 { \
207 kCLOCK_Trng0 \
208 }
209
210/*! @brief Clock ip name array for LPSPI. */
211#define LPSPI_CLOCKS \
212 { \
213 kCLOCK_Lpspi0, kCLOCK_Lpspi1, kCLOCK_Lpspi2, kCLOCK_Lpspi3 \
214 }
215
216/*! @brief Clock ip name array for TPM. */
217#define TPM_CLOCKS \
218 { \
219 kCLOCK_Tpm0, kCLOCK_Tpm1, kCLOCK_Tpm2, kCLOCK_Tpm3, kCLOCK_Tpm4, kCLOCK_Tpm5, kCLOCK_Tpm6, kCLOCK_Tpm7 \
220 }
221
222/*! @brief Clock ip name array for LPIT. */
223#define LPIT_CLOCKS \
224 { \
225 kCLOCK_Lpit0, kCLOCK_Lpit1 \
226 }
227
228/*! @brief Clock ip name array for CRC. */
229#define CRC_CLOCKS \
230 { \
231 kCLOCK_Crc0 \
232 }
233
234/*! @brief Clock ip name array for CMP. */
235#define CMP_CLOCKS \
236 { \
237 kCLOCK_Cmp0, kCLOCK_Cmp1 \
238 }
239
240/*! @brief Clock ip name array for XRDC. */
241#define XRDC_CLOCKS \
242 { \
243 kCLOCK_Xrdc0 \
244 }
245
246/*! @brief Clock ip name array for MU. */
247#define MU_CLOCKS \
248 { \
249 kCLOCK_MuA \
250 }
251
252/*! @brief Clock ip name array for WDOG. */
253#define WDOG_CLOCKS \
254 { \
255 kCLOCK_Wdog0, kCLOCK_Wdog1, kCLOCK_Wdog2 \
256 }
257
258/*! @brief Clock ip name array for LTC. */
259#define LTC_CLOCKS \
260 { \
261 kCLOCK_Ltc0 \
262 }
263
264/*! @brief Clock ip name array for DPM. */
265#define DPM_CLOCKS \
266 { \
267 kCLOCK_Dpm \
268 }
269
270/*! @brief Clock ip name array for SEMA42. */
271#define SEMA42_CLOCKS \
272 { \
273 kCLOCK_Sema420, kCLOCK_Sema421 \
274 }
275
276/*! @brief Clock ip name array for TPIU. */
277#define TPIU_CLOCKS \
278 { \
279 kCLOCK_Tpiu \
280 }
281
282/*! @brief Clock ip name array for QSPI. */
283#define QSPI_CLOCKS \
284 { \
285 kCLOCK_Qspi \
286 }
287
288/*!
289 * @brief LPO clock frequency.
290 */
291#define LPO_CLK_FREQ 1000U
292
293/*!
294 * @brief TPIU clock frequency.
295 */
296#define TPIU_CLK_FREQ 100000000U
297
298/*! @brief Clock name used to get clock frequency. */
299typedef enum _clock_name
300{
301
302 /* ---------------------------- System layer clock -----------------------*/
303 kCLOCK_CoreSysClk, /*!< Core/system clock */
304 kCLOCK_PlatClk, /*!< Platform clock */
305 kCLOCK_ExtClk, /*!< External clock */
306 kCLOCK_BusClk, /*!< Bus clock */
307 kCLOCK_SlowClk, /*!< Slow clock */
308
309 /* ------------------------------------ SCG clock ------------------------*/
310 kCLOCK_ScgSysOscClk, /*!< SCG system OSC clock. (SYSOSC) */
311 kCLOCK_ScgSircClk, /*!< SCG SIRC clock. */
312 kCLOCK_ScgFircClk, /*!< SCG FIRC clock. */
313 kCLOCK_ScgRtcOscClk, /*!< SCG RTC OSC clock. (ROSC) */
314 kCLOCK_ScgAuxPllClk, /*!< SCG auxiliary PLL clock. (AUXPLL) */
315 kCLOCK_ScgSysPllClk, /*!< SCG system PLL clock. (SYSPLL) */
316
317 kCLOCK_ScgSysOscAsyncDiv1Clk, /*!< SOSCDIV1_CLK. */
318 kCLOCK_ScgSysOscAsyncDiv2Clk, /*!< SOSCDIV2_CLK. */
319 kCLOCK_ScgSysOscAsyncDiv3Clk, /*!< SOSCDIV3_CLK. */
320
321 kCLOCK_ScgSircAsyncDiv1Clk, /*!< SIRCDIV1_CLK. */
322 kCLOCK_ScgSircAsyncDiv2Clk, /*!< SIRCDIV2_CLK. */
323 kCLOCK_ScgSircAsyncDiv3Clk, /*!< SIRCDIV3_CLK. */
324
325 kCLOCK_ScgFircAsyncDiv1Clk, /*!< FIRCDIV1_CLK. */
326 kCLOCK_ScgFircAsyncDiv2Clk, /*!< FIRCDIV2_CLK. */
327 kCLOCK_ScgFircAsyncDiv3Clk, /*!< FIRCDIV3_CLK. */
328
329 kCLOCK_ScgSysPllPfd0Clk, /*!< spll pfd0. */
330 kCLOCK_ScgSysPllPfd1Clk, /*!< spll pfd1. */
331 kCLOCK_ScgSysPllPfd2Clk, /*!< spll pfd2. */
332 kCLOCK_ScgSysPllPfd3Clk, /*!< spll pfd3. */
333
334 kCLOCK_ScgAuxPllPfd0Clk, /*!< apll pfd0. */
335 kCLOCK_ScgAuxPllPfd1Clk, /*!< apll pfd1. */
336 kCLOCK_ScgAuxPllPfd2Clk, /*!< apll pfd2. */
337 kCLOCK_ScgAuxPllPfd3Clk, /*!< apll pfd3. */
338
339 kCLOCK_ScgSysPllAsyncDiv1Clk, /*!< SPLLDIV1_CLK. */
340 kCLOCK_ScgSysPllAsyncDiv2Clk, /*!< SPLLDIV2_CLK. */
341 kCLOCK_ScgSysPllAsyncDiv3Clk, /*!< SPLLDIV3_CLK. */
342
343 kCLOCK_ScgAuxPllAsyncDiv1Clk, /*!< APLLDIV1_CLK. */
344 kCLOCK_ScgAuxPllAsyncDiv2Clk, /*!< APLLDIV2_CLK. */
345 kCLOCK_ScgAuxPllAsyncDiv3Clk, /*!< APLLDIV3_CLK. */
346
347 /* -------------------------------- Other clock --------------------------*/
348 kCLOCK_LpoClk, /*!< LPO clock */
349 kCLOCK_Osc32kClk, /*!< External OSC 32K clock (OSC32KCLK) */
350 kCLOCK_ErClk, /*!< ERCLK. The external reference clock from SCG. */
351 kCLOCK_LvdsClk, /*!< LVDS pad input clock frequency. */
352} clock_name_t;
353
354#define kCLOCK_Osc0ErClk kCLOCK_ErClk /*!< For compatible with other MCG platforms. */
355#define kCLOCK_Er32kClk kCLOCK_Osc32kClk /*!< For compatible with other MCG platforms. */
356#define CLOCK_GetOsc0ErClkFreq CLOCK_GetErClkFreq /*!< For compatible with other MCG platforms. */
357#define CLOCK_GetEr32kClkFreq CLOCK_GetOsc32kClkFreq /*!< For compatible with other MCG platforms. */
358
359/*!
360 * @brief Clock source for peripherals that support various clock selections.
361 */
362typedef enum _clock_ip_src
363{
364 kCLOCK_IpSrcNone = 0U, /*!< Clock is off. */
365 kCLOCK_IpSrcSysOscAsync = 1U, /*!< SYSOSC platform or bus clock, depending on clock IP. */
366 kCLOCK_IpSrcSircAsync = 2U, /*!< SIRC platform or bus clock, depending on clock IP. */
367 kCLOCK_IpSrcFircAsync = 3U, /*!< FIRC platform or bus clock, depending on clock IP. */
368 kCLOCK_IpSrcRtcAuxPllAsync = 4U, /*!< RTC OSC clock or AUXPLL main clock, depending on clock IP. */
369 kCLOCK_IpSrcSystem = 5U, /*!< System platform or bus clock, depending on clock IP. */
370 kCLOCK_IpSrcSysPllAsync = 6U, /*!< SYSPLL platform or bus clock, depending on clock IP. */
371 kCLOCK_IpSrcPllPfdAsync = 7U, /*!< SYSPLL PFD3 or AUXPLL PFD0 clock, depending on clock IP. */
372} clock_ip_src_t;
373
374/*!
375 * @brief Clock source for LPTMR.
376 */
377typedef enum _clock_lptmr_src
378{
379 kCLOCK_LptmrSrcSircAsync = 0U, /*!< SIRC clock. */
380 kCLOCK_LptmrSrcLPO1K = 1U, /*!< LPO 1KHz clock. */
381 kCLOCK_LptmrSrcXTAL32K = 2U, /*!< RTC XTAL clock. */
382 kCLOCK_LptmrSrcExternal = 3U, /*!< External clock. */
383} clock_lptmr_src_t;
384
385/*!
386 * @brief Peripheral clock name difinition used for clock gate, clock source
387 * and clock divider setting. It is defined as the corresponding register address.
388 */
389typedef enum _clock_ip_name
390{
391 kCLOCK_IpInvalid = 0U,
392 /* PCC 0 */
393 kCLOCK_Dma0 = 0x41026020U,
394 kCLOCK_Rgpio2p0 = 0x4102603CU,
395 kCLOCK_Xrdc0 = 0x41026050U,
396 kCLOCK_Sema420 = 0x4102606CU,
397 kCLOCK_Dmamux0 = 0x41026080U,
398 kCLOCK_MuA = 0x41026088U,
399 kCLOCK_Wdog0 = 0x41026094U,
400 kCLOCK_Crc0 = 0x410260A4U,
401 kCLOCK_Ltc0 = 0x410260A8U,
402 kCLOCK_Trng0 = 0x410260B0U,
403 kCLOCK_Lpit0 = 0x410260B4U,
404 kCLOCK_Lptmr0 = 0x410260B8U,
405 kCLOCK_Lptmr1 = 0x410260BCU,
406 kCLOCK_Tpm0 = 0x410260C0U,
407 kCLOCK_Tpm1 = 0x410260C4U,
408 kCLOCK_Flexio0 = 0x410260C8U,
409 kCLOCK_Lpi2c0 = 0x410260CCU,
410 kCLOCK_Lpi2c1 = 0x410260D0U,
411 kCLOCK_Lpi2c2 = 0x410260D4U,
412 kCLOCK_Lpi2c3 = 0x410260D8U,
413 kCLOCK_Sai0 = 0x410260DCU,
414 kCLOCK_Lpspi0 = 0x410260E0U,
415 kCLOCK_Lpspi1 = 0x410260E4U,
416 kCLOCK_Lpuart0 = 0x410260E8U,
417 kCLOCK_Lpuart1 = 0x410260ECU,
418 kCLOCK_PctlA = 0x410260FCU,
419 kCLOCK_PctlB = 0x41026100U,
420 kCLOCK_Adc0 = 0x41026104U,
421 kCLOCK_Cmp0 = 0x41026108U,
422 kCLOCK_Cmp1 = 0x4102610CU,
423 kCLOCK_Dac0 = 0x41026110U,
424 kCLOCK_Dac1 = 0x41026114U,
425 kCLOCK_Snvs = 0x410261C0U,
426
427 /* PCC 1 */
428 kCLOCK_Tpiu = 0x410B2050U,
429 kCLOCK_Qspi = 0x410B2094U,
430 kCLOCK_Tpm2 = 0x410B20A0U,
431 kCLOCK_Tpm3 = 0x410B20A4U,
432 kCLOCK_Sai1 = 0x410B20A8U,
433 kCLOCK_Lpuart2 = 0x410B20ACU,
434 kCLOCK_Lpuart3 = 0x410B20B0U,
435 kCLOCK_Adc1 = 0x410B20B4U,
436
437 /* PCC 2 */
438 kCLOCK_Dma1 = 0x403F0020U,
439 kCLOCK_Rgpio2p1 = 0x403F003CU,
440 kCLOCK_Flexbus = 0x403F0040U,
441 kCLOCK_Sema421 = 0x403F006CU,
442 kCLOCK_Dmamux1 = 0x403F0084U,
443 kCLOCK_Caam = 0x403F0090U,
444 kCLOCK_Tpm4 = 0x403F0094U,
445 kCLOCK_Tpm5 = 0x403F0098U,
446 kCLOCK_Lpit1 = 0x403F009CU,
447 kCLOCK_Lpspi2 = 0x403F00A4U,
448 kCLOCK_Lpspi3 = 0x403F00A8U,
449 kCLOCK_Lpi2c4 = 0x403F00ACU,
450 kCLOCK_Lpi2c5 = 0x403F00B0U,
451 kCLOCK_Lpuart4 = 0x403F00B4U,
452 kCLOCK_Lpuart5 = 0x403F00B8U,
453 kCLOCK_Flexio1 = 0x403F00C4U,
454 kCLOCK_Usb0 = 0x403F00CCU,
455 kCLOCK_Usb1 = 0x403F00D0U,
456 kCLOCK_UsbPhy = 0x403F00D4U,
457 kCLOCK_UsbPl301 = 0x403F00D8U,
458 kCLOCK_Usdhc0 = 0x403F00DCU,
459 kCLOCK_Usdhc1 = 0x403F00E0U,
460 kCLOCK_Wdog1 = 0x403F00F4U,
461 kCLOCK_Wdog2 = 0x403F010CU,
462
463 /* PCC 3 */
464 kCLOCK_Tpm6 = 0x40B30084U,
465 kCLOCK_Tpm7 = 0x40B30088U,
466 kCLOCK_Lpi2c6 = 0x40B30090U,
467 kCLOCK_Lpi2c7 = 0x40B30094U,
468 kCLOCK_Lpuart6 = 0x40B30098U,
469 kCLOCK_Lpuart7 = 0x40B3009CU,
470 kCLOCK_Viu = 0x40B300A0U,
471 kCLOCK_Dsi = 0x40B300A4U,
472 kCLOCK_Lcdif = 0x40B300A8U,
473 kCLOCK_Mmdc = 0x40B300ACU,
474 kCLOCK_PctlC = 0x40B300B8U,
475 kCLOCK_PctlD = 0x40B300BCU,
476 kCLOCK_PctlE = 0x40B300C0U,
477 kCLOCK_PctlF = 0x40B300C4U,
478 kCLOCK_Gpu3D = 0x40B30140U,
479 kCLOCK_Gpu2D = 0x40B30144U,
480} clock_ip_name_t;
481
482/*!
483 * @brief SCG status return codes.
484 */
485enum
486{
487 kStatus_SCG_Busy = MAKE_STATUS(kStatusGroup_SCG, 1), /*!< Clock is busy. */
488 kStatus_SCG_InvalidSrc = MAKE_STATUS(kStatusGroup_SCG, 2) /*!< Invalid source. */
489};
490
491/*!
492 * @brief SCG system clock type.
493 */
494typedef enum _scg_sys_clk
495{
496 kSCG_SysClkSlow, /*!< System slow clock. */
497 kSCG_SysClkBus, /*!< Bus clock. */
498 kSCG_SysClkExt, /*!< External clock. */
499 kSCG_SysClkPlat, /*!< Platform clock. */
500 kSCG_SysClkCore, /*!< Core clock. */
501} scg_sys_clk_t;
502
503/*!
504 * @brief SCG system clock source.
505 */
506typedef enum _scg_sys_clk_src
507{
508 kSCG_SysClkSrcSysOsc = 1U, /*!< System OSC. */
509 kSCG_SysClkSrcSirc = 2U, /*!< Slow IRC. */
510 kSCG_SysClkSrcFirc = 3U, /*!< Fast IRC. */
511 kSCG_SysClkSrcRosc = 4U, /*!< RTC OSC. */
512 kSCG_SysClkSrcAuxPll = 5U, /*!< Auxiliary PLL. */
513 kSCG_SysClkSrcSysPll = 6U /*!< System PLL. */
514} scg_sys_clk_src_t;
515
516/*!
517 * @brief SCG system clock divider value.
518 */
519typedef enum _scg_sys_clk_div
520{
521 kSCG_SysClkDivBy1 = 0U, /*!< Divided by 1. */
522 kSCG_SysClkDivBy2 = 1U, /*!< Divided by 2. */
523 kSCG_SysClkDivBy3 = 2U, /*!< Divided by 3. */
524 kSCG_SysClkDivBy4 = 3U, /*!< Divided by 4. */
525 kSCG_SysClkDivBy5 = 4U, /*!< Divided by 5. */
526 kSCG_SysClkDivBy6 = 5U, /*!< Divided by 6. */
527 kSCG_SysClkDivBy7 = 6U, /*!< Divided by 7. */
528 kSCG_SysClkDivBy8 = 7U, /*!< Divided by 8. */
529 kSCG_SysClkDivBy9 = 8U, /*!< Divided by 9. */
530 kSCG_SysClkDivBy10 = 9U, /*!< Divided by 10. */
531 kSCG_SysClkDivBy11 = 10U, /*!< Divided by 11. */
532 kSCG_SysClkDivBy12 = 11U, /*!< Divided by 12. */
533 kSCG_SysClkDivBy13 = 12U, /*!< Divided by 13. */
534 kSCG_SysClkDivBy14 = 13U, /*!< Divided by 14. */
535 kSCG_SysClkDivBy15 = 14U, /*!< Divided by 15. */
536 kSCG_SysClkDivBy16 = 15U /*!< Divided by 16. */
537} scg_sys_clk_div_t;
538
539/*!
540 * @brief SCG system clock configuration.
541 */
542typedef struct _scg_sys_clk_config
543{
544 uint32_t divSlow : 4; /*!< Slow clock divider, see @ref scg_sys_clk_div_t. */
545 uint32_t divBus : 4; /*!< Bus clock divider, see @ref scg_sys_clk_div_t. */
546 uint32_t : 4; /*!< Reserved. */
547 uint32_t divPlat : 4; /*!< Platform clock divider, which can only be divided by 1. See @ref kSCG_SysClkDivBy1.*/
548 uint32_t divCore : 4; /*!< Core clock divider, see @ref scg_sys_clk_div_t. */
549 uint32_t : 4; /*!< Reserved. */
550 uint32_t src : 4; /*!< System clock source, see @ref scg_sys_clk_src_t. */
551 uint32_t : 4; /*!< reserved. */
552} scg_sys_clk_config_t;
553
554/*!
555 * @brief SCG clock out configuration (CLKOUTSEL).
556 */
557typedef enum _clock_clkout_src
558{
559 kClockClkoutSelScgExt = 0U, /*!< SCG external clock. */
560 kClockClkoutSelSysOsc = 1U, /*!< System OSC. */
561 kClockClkoutSelSirc = 2U, /*!< Slow IRC. */
562 kClockClkoutSelFirc = 3U, /*!< Fast IRC. */
563 kClockClkoutSelScgRtcOsc = 4U, /*!< SCG RTC OSC clock. */
564 kClockClkoutSelScgAuxPll = 5U, /*!< SCG Auxiliary PLL clock. */
565 kClockClkoutSelSysPll = 6U /*!< System PLL. */
566} clock_clkout_src_t;
567
568/*!
569 * @brief SCG asynchronous clock type.
570 */
571typedef enum _scg_async_clk
572{
573 kSCG_AsyncDiv1Clk, /*!< The async clock by DIV1, e.g. SOSCDIV1_CLK, SIRCDIV1_CLK. */
574 kSCG_AsyncDiv2Clk, /*!< The async clock by DIV2, e.g. SOSCDIV2_CLK, SIRCDIV2_CLK. */
575 kSCG_AsyncDiv3Clk /*!< The async clock by DIV3, e.g. SOSCDIV3_CLK, SIRCDIV3_CLK. */
576} scg_async_clk_t;
577
578/*!
579 * @brief SCG asynchronous clock divider value.
580 */
581typedef enum scg_async_clk_div
582{
583 kSCG_AsyncClkDisable = 0U, /*!< Clock output is disabled. */
584 kSCG_AsyncClkDivBy1 = 1U, /*!< Divided by 1. */
585 kSCG_AsyncClkDivBy2 = 2U, /*!< Divided by 2. */
586 kSCG_AsyncClkDivBy4 = 3U, /*!< Divided by 4. */
587 kSCG_AsyncClkDivBy8 = 4U, /*!< Divided by 8. */
588 kSCG_AsyncClkDivBy16 = 5U, /*!< Divided by 16. */
589 kSCG_AsyncClkDivBy32 = 6U, /*!< Divided by 32. */
590 kSCG_AsyncClkDivBy64 = 7U /*!< Divided by 64. */
591} scg_async_clk_div_t;
592
593/*!
594 * @brief SCG system OSC monitor mode.
595 */
596typedef enum _scg_sosc_monitor_mode
597{
598 kSCG_SysOscMonitorDisable = 0U, /*!< Monitor disabled. */
599 kSCG_SysOscMonitorInt = SCG_SOSCCSR_SOSCCM_MASK, /*!< Interrupt when the system OSC error is detected. */
600 kSCG_SysOscMonitorReset =
601 SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCCMRE_MASK /*!< Reset when the system OSC error is detected. */
602} scg_sosc_monitor_mode_t;
603
604/*! @brief OSC work mode. */
605typedef enum _scg_sosc_mode
606{
607 kSCG_SysOscModeExt = 0U, /*!< Use external clock. */
608 kSCG_SysOscModeOscLowPower = SCG_SOSCCFG_EREFS_MASK, /*!< Oscillator low power. */
609 kSCG_SysOscModeOscHighGain = SCG_SOSCCFG_EREFS_MASK | SCG_SOSCCFG_HGO_MASK /*!< Oscillator high gain. */
610} scg_sosc_mode_t;
611
612/*! @brief OSC enable mode. */
613enum _scg_sosc_enable_mode
614{
615 kSCG_SysOscEnable = SCG_SOSCCSR_SOSCEN_MASK, /*!< Enable OSC clock. */
616 kSCG_SysOscEnableInStop = SCG_SOSCCSR_SOSCSTEN_MASK, /*!< Enable OSC in stop mode. */
617 kSCG_SysOscEnableInLowPower = SCG_SOSCCSR_SOSCLPEN_MASK, /*!< Enable OSC in low power mode. */
618};
619
620/*!
621 * @brief SCG system OSC configuration.
622 */
623typedef struct _scg_sosc_config
624{
625 uint32_t freq; /*!< System OSC frequency. */
626 scg_sosc_monitor_mode_t monitorMode; /*!< Clock monitor mode selected. */
627 uint8_t enableMode; /*!< Enable mode, OR'ed value of _scg_sosc_enable_mode. */
628
629 scg_async_clk_div_t div1; /*!< SOSCDIV1 value. */
630 scg_async_clk_div_t div2; /*!< SOSCDIV2 value. */
631 scg_async_clk_div_t div3; /*!< SOSCDIV3 value. */
632
633 scg_sosc_mode_t workMode; /*!< OSC work mode. */
634} scg_sosc_config_t;
635
636/*!
637 * @brief SCG slow IRC clock frequency range.
638 */
639typedef enum _scg_sirc_range
640{
641 kSCG_SircRangeLow, /*!< Slow IRC low range clock (2 MHz, 4 MHz for i.MX 7ULP). */
642 kSCG_SircRangeHigh /*!< Slow IRC high range clock (8 MHz, 16 MHz for i.MX 7ULP). */
643} scg_sirc_range_t;
644
645/*! @brief SIRC enable mode. */
646enum _scg_sirc_enable_mode
647{
648 kSCG_SircEnable = SCG_SIRCCSR_SIRCEN_MASK, /*!< Enable SIRC clock. */
649 kSCG_SircEnableInStop = SCG_SIRCCSR_SIRCSTEN_MASK, /*!< Enable SIRC in stop mode. */
650 kSCG_SircEnableInLowPower = SCG_SIRCCSR_SIRCLPEN_MASK /*!< Enable SIRC in low power mode. */
651};
652
653/*!
654 * @brief SCG slow IRC clock configuration.
655 */
656typedef struct _scg_sirc_config
657{
658 uint32_t enableMode; /*!< Enable mode, OR'ed value of _scg_sirc_enable_mode. */
659 scg_async_clk_div_t div1; /*!< SIRCDIV1 value. */
660 scg_async_clk_div_t div2; /*!< SIRCDIV2 value. */
661 scg_async_clk_div_t div3; /*!< SIRCDIV3 value. */
662
663 scg_sirc_range_t range; /*!< Slow IRC frequency range. */
664} scg_sirc_config_t;
665
666/*!
667 * @brief SCG fast IRC trim mode.
668 */
669typedef enum _scg_firc_trim_mode
670{
671 kSCG_FircTrimNonUpdate = SCG_FIRCCSR_FIRCTREN_MASK,
672 /*!< FIRC trim enable but not enable trim value update. In this mode, the
673 trim value is fixed to the initialized value which is defined by
674 trimCoar and trimFine in configure structure \ref scg_firc_trim_config_t.*/
675
676 kSCG_FircTrimUpdate = SCG_FIRCCSR_FIRCTREN_MASK | SCG_FIRCCSR_FIRCTRUP_MASK
677 /*!< FIRC trim enable and trim value update enable. In this mode, the trim
678 value is auto update. */
679
680} scg_firc_trim_mode_t;
681
682/*!
683 * @brief SCG fast IRC trim predivided value for system OSC.
684 */
685typedef enum _scg_firc_trim_div
686{
687 kSCG_FircTrimDivBy1, /*!< Divided by 1. */
688 kSCG_FircTrimDivBy128, /*!< Divided by 128. */
689 kSCG_FircTrimDivBy256, /*!< Divided by 256. */
690 kSCG_FircTrimDivBy512, /*!< Divided by 512. */
691 kSCG_FircTrimDivBy1024, /*!< Divided by 1024. */
692 kSCG_FircTrimDivBy2048 /*!< Divided by 2048. */
693} scg_firc_trim_div_t;
694
695/*!
696 * @brief SCG fast IRC trim source.
697 */
698typedef enum _scg_firc_trim_src
699{
700 kSCG_FircTrimSrcUsb0 = 0U, /*!< USB0 start of frame (1kHz). */
701 kSCG_FircTrimSrcUsb1 = 1U, /*!< USB1 start of frame (1kHz). */
702 kSCG_FircTrimSrcSysOsc = 2U, /*!< System OSC. */
703 kSCG_FircTrimSrcRtcOsc = 3U, /*!< RTC OSC (32.768 kHz). */
704} scg_firc_trim_src_t;
705
706/*!
707 * @brief SCG fast IRC clock trim configuration.
708 */
709typedef struct _scg_firc_trim_config
710{
711 scg_firc_trim_mode_t trimMode; /*!< FIRC trim mode. */
712 scg_firc_trim_src_t trimSrc; /*!< Trim source. */
713 scg_firc_trim_div_t trimDiv; /*!< Trim predivided value for the system OSC. */
714
715 uint8_t trimCoar; /*!< Trim coarse value; Irrelevant if trimMode is kSCG_FircTrimUpdate. */
716 uint8_t trimFine; /*!< Trim fine value; Irrelevant if trimMode is kSCG_FircTrimUpdate. */
717} scg_firc_trim_config_t;
718
719/*!
720 * @brief SCG fast IRC clock frequency range.
721 */
722typedef enum _scg_firc_range
723{
724 kSCG_FircRange48M, /*!< Fast IRC is trimmed to 48 MHz. */
725 kSCG_FircRange52M, /*!< Fast IRC is trimmed to 52 MHz. */
726 kSCG_FircRange56M, /*!< Fast IRC is trimmed to 56 MHz. */
727 kSCG_FircRange60M /*!< Fast IRC is trimmed to 60 MHz. */
728} scg_firc_range_t;
729
730/*! @brief FIRC enable mode. */
731enum _scg_firc_enable_mode
732{
733 kSCG_FircEnable = SCG_FIRCCSR_FIRCEN_MASK, /*!< Enable FIRC clock. */
734 kSCG_FircEnableInStop = SCG_FIRCCSR_FIRCSTEN_MASK, /*!< Enable FIRC in stop mode. */
735};
736
737/*!
738 * @brief SCG fast IRC clock configuration.
739 */
740typedef struct _scg_firc_config_t
741{
742 uint32_t enableMode; /*!< Enable mode, OR'ed value of _scg_firc_enable_mode. */
743
744 scg_async_clk_div_t div1; /*!< FIRCDIV1 value. */
745 scg_async_clk_div_t div2; /*!< FIRCDIV2 value. */
746 scg_async_clk_div_t div3; /*!< FIRCDIV3 value. */
747
748 scg_firc_range_t range; /*!< Fast IRC frequency range. */
749
750 const scg_firc_trim_config_t *trimConfig; /*!< Pointer to the FIRC trim configuration; set NULL to disable trim. */
751} scg_firc_config_t;
752
753/*!
754 * @brief SCG system PLL clock source.
755 */
756typedef enum _scg_spll_src
757{
758 kSCG_SysPllSrcSysOsc, /*!< System PLL clock source is system OSC. */
759 kSCG_SysPllSrcFirc /*!< System PLL clock source is fast IRC. */
760} scg_spll_src_t;
761
762/*! @brief SPLL enable mode. */
763enum _scg_spll_enable_mode
764{
765 kSCG_SysPllEnable = SCG_SPLLCSR_SPLLEN_MASK, /*!< Enable SPLL clock. */
766 kSCG_SysPllEnableInStop = SCG_SPLLCSR_SPLLSTEN_MASK /*!< Enable SPLL in stop mode. */
767};
768
769/*!
770 * @brief SCG system PLL PFD clouk out select.
771 */
772typedef enum _scg_spll_pfd_clkout
773{
774 kSCG_SysPllPfd0Clk = 0U, /*!< PFD0 output clock selected. */
775 kSCG_SysPllPfd1Clk = 8U, /*!< PFD1 output clock selected. */
776 kSCG_SysPllPfd2Clk = 16U, /*!< PFD2 output clock selected. */
777 kSCG_SysPllPfd3Clk = 24U /*!< PFD3 output clock selected. */
778} scg_spll_pfd_clkout_t;
779
780/*!
781 * @brief SCG system PLL configuration.
782 */
783typedef struct _scg_spll_config
784{
785 uint8_t enableMode; /*!< Enable mode, OR'ed value of _scg_spll_enable_mode */
786
787 scg_async_clk_div_t div1; /*!< SPLLDIV1 value. */
788 scg_async_clk_div_t div2; /*!< SPLLDIV2 value. */
789 scg_async_clk_div_t div3; /*!< SPLLDIV3 value. */
790
791 scg_spll_src_t src; /*!< Clock source. */
792 bool isPfdSelected; /*!< SPLL PFD output clock selected. */
793 uint8_t prediv; /*!< PLL reference clock divider. */
794 scg_spll_pfd_clkout_t pfdClkout; /*!< PLL PFD clouk out select. */
795 uint8_t mult; /*!< System PLL multiplier. */
796} scg_spll_config_t;
797
798/*!
799 * @brief SCG RTC OSC monitor mode.
800 */
801typedef enum _scg_rosc_monitor_mode
802{
803 kSCG_rtcOscMonitorDisable = 0U, /*!< Monitor disable. */
804 kSCG_rtcOscMonitorInt = SCG_ROSCCSR_ROSCCM_MASK, /*!< Interrupt when the RTC OSC error is detected. */
805 kSCG_rtcOscMonitorReset =
806 SCG_ROSCCSR_ROSCCM_MASK | SCG_ROSCCSR_ROSCCMRE_MASK /*!< Reset when the RTC OSC error is detected. */
807} scg_rosc_monitor_mode_t;
808
809/*!
810 * @brief SCG RTC OSC configuration.
811 */
812typedef struct _scg_rosc_config
813{
814 scg_rosc_monitor_mode_t monitorMode; /*!< Clock monitor mode selected. */
815} scg_rosc_config_t;
816
817/*!
818 * @brief SCG auxiliary PLL clock source.
819 */
820typedef enum _scg_apll_src
821{
822 kSCG_AuxPllSrcSysOsc, /*!< Auxiliary PLL clock source is the system OSC. */
823 kSCG_AuxPllSrcFirc /*!< Auxiliary PLL clock source is the fast IRC. */
824} scg_apll_src_t;
825
826/*! @brief APLL enable mode. */
827enum _scg_apll_enable_mode
828{
829 kSCG_AuxPllEnable = SCG_APLLCSR_APLLEN_MASK, /*!< Enable APLL clock. */
830 kSCG_AuxPllEnableInStop = SCG_APLLCSR_APLLSTEN_MASK /*!< Enable APLL in stop mode. */
831};
832
833/*!
834 * @brief SCG auxiliary PLL PFD clouk out select.
835 */
836typedef enum _scg_apll_pfd_clkout
837{
838 kSCG_AuxPllPfd0Clk = 0U, /*!< PFD0 output clock selected. */
839 kSCG_AuxPllPfd1Clk = 8U, /*!< PFD1 output clock selected. */
840 kSCG_AuxPllPfd2Clk = 16U, /*!< PFD2 output clock selected. */
841 kSCG_AuxPllPfd3Clk = 24U /*!< PFD3 output clock selected. */
842} scg_apll_pfd_clkout_t;
843
844/*!
845 * @brief SCG auxiliary PLL configuration.
846 */
847typedef struct _scg_apll_config
848{
849 uint8_t enableMode; /*!< Enable mode, OR'ed value of _scg_apll_enable_mode */
850
851 scg_async_clk_div_t div1; /*!< APLLDIV1 value. */
852 scg_async_clk_div_t div2; /*!< APLLDIV2 value. */
853 scg_async_clk_div_t div3; /*!< APLLDIV3 value. */
854
855 scg_apll_src_t src; /*!< Clock source. */
856 bool isPfdSelected; /*!< APLL PFD output clock selected. */
857 uint8_t prediv; /*!< PLL reference clock divider. */
858 scg_apll_pfd_clkout_t pfdClkout; /*!< SCG auxiliary PLL PFD clouk out select. */
859 uint8_t mult; /*!< Auxiliary PLL multiplier. */
860 scg_sys_clk_div_t pllPostdiv1; /*!< Auxiliary PLL Post Clock Divide1 Ratio. */
861 scg_sys_clk_div_t pllPostdiv2; /*!< Auxiliary PLL Post Clock Divide2 Ratio. */
862
863 uint32_t num : 30; /*!< 30-bit numerator of the Auxiliary PLL Fractional-Loop divider. */
864 uint32_t denom : 30; /*!< 30-bit denominator of the Auxiliary PLL Fractional-Loop divider. */
865} scg_apll_config_t;
866
867/*******************************************************************************
868 * API
869 ******************************************************************************/
870
871#if defined(__cplusplus)
872extern "C" {
873#endif /* __cplusplus */
874
875/*!
876 * @brief Enable the clock for specific IP.
877 *
878 * @param name Which clock to enable, see \ref clock_ip_name_t.
879 */
880static inline void CLOCK_EnableClock(clock_ip_name_t name)
881{
882 assert((*(volatile uint32_t *)(uint32_t)name) & PCC_CLKCFG_PR_MASK);
883
884 (*(volatile uint32_t *)(uint32_t)name) |= PCC_CLKCFG_CGC_MASK;
885}
886
887/*!
888 * @brief Disable the clock for specific IP.
889 *
890 * @param name Which clock to disable, see \ref clock_ip_name_t.
891 */
892static inline void CLOCK_DisableClock(clock_ip_name_t name)
893{
894 assert((*(volatile uint32_t *)(uint32_t)name) & PCC_CLKCFG_PR_MASK);
895
896 (*(volatile uint32_t *)(uint32_t)name) &= ~PCC_CLKCFG_CGC_MASK;
897}
898
899/*!
900 * @brief Check whether the clock is already enabled and configured by
901 * any other core.
902 *
903 * @param name Which peripheral to check, see \ref clock_ip_name_t.
904 * @return True if clock is already enabled, otherwise false.
905 */
906static inline bool CLOCK_IsEnabledByOtherCore(clock_ip_name_t name)
907{
908 assert((*(volatile uint32_t *)(uint32_t)name) & PCC_CLKCFG_PR_MASK);
909
910 return (((*(volatile uint32_t *)(uint32_t)name) & PCC_CLKCFG_INUSE_MASK) != 0UL) ? true : false;
911}
912
913/*!
914 * @brief Set the clock source for specific IP module.
915 *
916 * Set the clock source for specific IP, not all modules need to set the
917 * clock source, should only use this function for the modules need source
918 * setting.
919 *
920 * @param name Which peripheral to check, see \ref clock_ip_name_t.
921 * @param src Clock source to set.
922 */
923static inline void CLOCK_SetIpSrc(clock_ip_name_t name, clock_ip_src_t src)
924{
925 uint32_t reg = (*(volatile uint32_t *)(uint32_t)name);
926
927 assert(reg & PCC_CLKCFG_PR_MASK);
928 assert(0UL == (reg & PCC_CLKCFG_INUSE_MASK)); /* Should not change if clock has been enabled by other core. */
929
930 reg = (reg & ~PCC_CLKCFG_PCS_MASK) | PCC_CLKCFG_PCS(src);
931
932 /*
933 * If clock is already enabled, first disable it, then set the clock
934 * source and re-enable it.
935 */
936 (*(volatile uint32_t *)(uint32_t)name) = reg & ~PCC_CLKCFG_CGC_MASK;
937 (*(volatile uint32_t *)(uint32_t)name) = reg;
938}
939
940/*!
941 * @brief Set the clock source and divider for specific IP module.
942 *
943 * Set the clock source and divider for specific IP, not all modules need to
944 * set the clock source and divider, should only use this function for the
945 * modules need source and divider setting.
946 *
947 * Divider output clock = Divider input clock x [(fracValue+1)/(divValue+1)]).
948 *
949 * @param name Which peripheral to check, see \ref clock_ip_name_t.
950 * @param src Clock source to set.
951 * @param divValue The divider value.
952 * @param fracValue The fraction multiply value.
953 */
954static inline void CLOCK_SetIpSrcDiv(clock_ip_name_t name, clock_ip_src_t src, uint8_t divValue, uint8_t fracValue)
955{
956 uint32_t reg = (*(volatile uint32_t *)(uint32_t)name);
957
958 assert(reg & PCC_CLKCFG_PR_MASK);
959 assert(0UL == (reg & PCC_CLKCFG_INUSE_MASK)); /* Should not change if clock has been enabled by other core. */
960
961 if ((kCLOCK_Sai0 == name) || (kCLOCK_Sai1 == name))
962 {
963 reg =
964 (reg & ~(PCC_CLKCFG_PCS_MASK | PCC1_PCC_SAI1_PCD_MASK)) | PCC_CLKCFG_PCS(src) | PCC1_PCC_SAI1_PCD(divValue);
965 }
966 else
967 {
968 reg = (reg & ~(PCC_CLKCFG_PCS_MASK | PCC_CLKCFG_FRAC_MASK | PCC_CLKCFG_PCD_MASK)) | PCC_CLKCFG_PCS(src) |
969 PCC_CLKCFG_PCD(divValue) | PCC_CLKCFG_FRAC(fracValue);
970 }
971
972 /*
973 * If clock is already enabled, first disable it, then set the clock
974 * source and re-enable it.
975 */
976 (*(volatile uint32_t *)(uint32_t)name) = reg & ~PCC_CLKCFG_CGC_MASK;
977 (*(volatile uint32_t *)(uint32_t)name) = reg;
978}
979
980/*!
981 * @brief Gets the clock frequency for a specific clock name.
982 *
983 * This function checks the current clock configurations and then calculates
984 * the clock frequency for a specific clock name defined in clock_name_t.
985 *
986 * @param clockName Clock names defined in clock_name_t
987 * @return Clock frequency value in hertz
988 */
989uint32_t CLOCK_GetFreq(clock_name_t clockName);
990
991/*!
992 * @brief Get the core clock or system clock frequency.
993 *
994 * @return Clock frequency in Hz.
995 */
996uint32_t CLOCK_GetCoreSysClkFreq(void);
997
998/*!
999 * @brief Get the platform clock frequency.
1000 *
1001 * @return Clock frequency in Hz.
1002 */
1003uint32_t CLOCK_GetPlatClkFreq(void);
1004
1005/*!
1006 * @brief Get the external clock frequency.
1007 *
1008 * @return Clock frequency in Hz.
1009 */
1010uint32_t CLOCK_GetExtClkFreq(void);
1011
1012/*!
1013 * @brief Get the bus clock frequency.
1014 *
1015 * @return Clock frequency in Hz.
1016 */
1017uint32_t CLOCK_GetBusClkFreq(void);
1018
1019/*!
1020 * @brief Get the slow clock frequency.
1021 *
1022 * @return Clock frequency in Hz.
1023 */
1024uint32_t CLOCK_GetSlowClkFreq(void);
1025
1026/*!
1027 * @brief Get the OSC 32K clock frequency (OSC32KCLK).
1028 *
1029 * @return Clock frequency in Hz.
1030 */
1031uint32_t CLOCK_GetOsc32kClkFreq(void);
1032
1033/*!
1034 * @brief Get the external reference clock frequency (ERCLK).
1035 *
1036 * @return Clock frequency in Hz.
1037 */
1038uint32_t CLOCK_GetErClkFreq(void);
1039
1040/*!
1041 * @brief Get the external LVDS pad clock frequency (LVDS).
1042 *
1043 * @return Clock frequency in Hz.
1044 */
1045uint32_t CLOCK_GetLvdsClkFreq(void);
1046
1047/*!
1048 * @brief Gets the clock frequency for a specific IP module.
1049 *
1050 * This function gets the IP module clock frequency based on PCC registers. It is
1051 * only used for the IP modules which could select clock source by PCC[PCS].
1052 *
1053 * @param name Which peripheral to get, see \ref clock_ip_name_t.
1054 * @return Clock frequency value in hertz
1055 */
1056uint32_t CLOCK_GetIpFreq(clock_ip_name_t name);
1057
1058/*!
1059 * @name MCU System Clock.
1060 * @{
1061 */
1062
1063/*!
1064 * @brief Gets the SCG system clock frequency.
1065 *
1066 * This function gets the SCG system clock frequency. These clocks are used for
1067 * core, platform, external, and bus clock domains.
1068 *
1069 * @param type Which type of clock to get, core clock or slow clock.
1070 * @return Clock frequency.
1071 */
1072uint32_t CLOCK_GetSysClkFreq(scg_sys_clk_t type);
1073
1074/*!
1075 * @brief Sets the system clock configuration for VLPR mode.
1076 *
1077 * This function sets the system clock configuration for VLPR mode.
1078 *
1079 * @param config Pointer to the configuration.
1080 */
1081static inline void CLOCK_SetVlprModeSysClkConfig(const scg_sys_clk_config_t *config)
1082{
1083 assert(config);
1084
1085 SCG->VCCR = *(const uint32_t *)(uint32_t)config;
1086}
1087
1088/*!
1089 * @brief Sets the system clock configuration for RUN mode.
1090 *
1091 * This function sets the system clock configuration for RUN mode.
1092 *
1093 * @param config Pointer to the configuration.
1094 */
1095static inline void CLOCK_SetRunModeSysClkConfig(const scg_sys_clk_config_t *config)
1096{
1097 assert(config);
1098
1099 SCG->RCCR = *(const uint32_t *)(uint32_t)config;
1100}
1101
1102/*!
1103 * @brief Sets the system clock configuration for HSRUN mode.
1104 *
1105 * This function sets the system clock configuration for HSRUN mode.
1106 *
1107 * @param config Pointer to the configuration.
1108 */
1109static inline void CLOCK_SetHsrunModeSysClkConfig(const scg_sys_clk_config_t *config)
1110{
1111 assert(config);
1112
1113 SCG->HCCR = *(const uint32_t *)(uint32_t)config;
1114}
1115
1116/*!
1117 * @brief Gets the system clock configuration in the current power mode.
1118 *
1119 * This function gets the system configuration in the current power mode.
1120 *
1121 * @param config Pointer to the configuration.
1122 */
1123static inline void CLOCK_GetCurSysClkConfig(scg_sys_clk_config_t *config)
1124{
1125 assert(config);
1126
1127 *(uint32_t *)(uint32_t)config = SCG->CSR;
1128}
1129
1130/*!
1131 * @brief Sets the clock out selection.
1132 *
1133 * This function sets the clock out selection (CLKOUTSEL).
1134 *
1135 * @param setting The selection to set.
1136 * @return The current clock out selection.
1137 */
1138static inline void CLOCK_SetClkOutSel(clock_clkout_src_t setting)
1139{
1140 SCG->CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting);
1141}
1142/* @} */
1143
1144/*!
1145 * @name SCG System OSC Clock.
1146 * @{
1147 */
1148
1149/*!
1150 * @brief Initializes the SCG system OSC.
1151 *
1152 * This function enables the SCG system OSC clock according to the
1153 * configuration.
1154 *
1155 * @param config Pointer to the configuration structure.
1156 * @retval kStatus_Success System OSC is initialized.
1157 * @retval kStatus_SCG_Busy System OSC has been enabled and is used by the system clock.
1158 * @retval kStatus_ReadOnly System OSC control register is locked.
1159 *
1160 * @note This function can't detect whether the system OSC has been enabled and
1161 * used by an IP.
1162 */
1163status_t CLOCK_InitSysOsc(const scg_sosc_config_t *config);
1164
1165/*!
1166 * @brief De-initializes the SCG system OSC.
1167 *
1168 * This function disables the SCG system OSC clock.
1169 *
1170 * @retval kStatus_Success System OSC is deinitialized.
1171 * @retval kStatus_SCG_Busy System OSC is used by the system clock.
1172 * @retval kStatus_ReadOnly System OSC control register is locked.
1173 *
1174 * @note This function can't detect whether the system OSC is used by an IP.
1175 */
1176status_t CLOCK_DeinitSysOsc(void);
1177
1178/*!
1179 * @brief Set the asynchronous clock divider.
1180 *
1181 * @param asyncClk Which asynchronous clock to configure.
1182 * @param divider The divider value to set.
1183 *
1184 * @note There might be glitch when changing the asynchronous divider, so make sure
1185 * the asynchronous clock is not used while changing divider.
1186 */
1187static inline void CLOCK_SetSysOscAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
1188{
1189 uint32_t reg = SCG->SOSCDIV;
1190
1191 switch (asyncClk)
1192 {
1193 case kSCG_AsyncDiv3Clk:
1194 reg = (reg & ~SCG_SOSCDIV_SOSCDIV3_MASK) | SCG_SOSCDIV_SOSCDIV3(divider);
1195 break;
1196 case kSCG_AsyncDiv2Clk:
1197 reg = (reg & ~SCG_SOSCDIV_SOSCDIV2_MASK) | SCG_SOSCDIV_SOSCDIV2(divider);
1198 break;
1199 default:
1200 reg = (reg & ~SCG_SOSCDIV_SOSCDIV1_MASK) | SCG_SOSCDIV_SOSCDIV1(divider);
1201 break;
1202 }
1203
1204 SCG->SOSCDIV = reg;
1205}
1206
1207/*!
1208 * @brief Gets the SCG system OSC clock frequency (SYSOSC).
1209 *
1210 * @return Clock frequency; If the clock is invalid, returns 0.
1211 */
1212uint32_t CLOCK_GetSysOscFreq(void);
1213
1214/*!
1215 * @brief Gets the SCG asynchronous clock frequency from the system OSC.
1216 *
1217 * @param type The asynchronous clock type.
1218 * @return Clock frequency; If the clock is invalid, returns 0.
1219 */
1220uint32_t CLOCK_GetSysOscAsyncFreq(scg_async_clk_t type);
1221
1222/*!
1223 * @brief Checks whether the system OSC clock error occurs.
1224 *
1225 * @return True if the error occurs, false if not.
1226 */
1227static inline bool CLOCK_IsSysOscErr(void)
1228{
1229 return ((SCG->SOSCCSR & SCG_SOSCCSR_SOSCERR_MASK) == SCG_SOSCCSR_SOSCERR_MASK);
1230}
1231
1232/*!
1233 * @brief Clears the system OSC clock error.
1234 */
1235static inline void CLOCK_ClearSysOscErr(void)
1236{
1237 SCG->SOSCCSR |= SCG_SOSCCSR_SOSCERR_MASK;
1238}
1239
1240/*!
1241 * @brief Sets the system OSC monitor mode.
1242 *
1243 * This function sets the system OSC monitor mode. The mode can be disabled,
1244 * it can generate an interrupt when the error is disabled, or reset when the error is detected.
1245 *
1246 * @param mode Monitor mode to set.
1247 */
1248static inline void CLOCK_SetSysOscMonitorMode(scg_sosc_monitor_mode_t mode)
1249{
1250 uint32_t reg = SCG->SOSCCSR;
1251
1252 reg &= ~(SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCCMRE_MASK);
1253
1254 reg |= (uint32_t)mode;
1255
1256 SCG->SOSCCSR = reg;
1257}
1258
1259/*!
1260 * @brief Checks whether the system OSC clock is valid.
1261 *
1262 * @return True if clock is valid, false if not.
1263 */
1264static inline bool CLOCK_IsSysOscValid(void)
1265{
1266 return ((SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) == SCG_SOSCCSR_SOSCVLD_MASK);
1267}
1268/* @} */
1269
1270/*!
1271 * @name SCG Slow IRC Clock.
1272 * @{
1273 */
1274
1275/*!
1276 * @brief Initializes the SCG slow IRC clock.
1277 *
1278 * This function enables the SCG slow IRC clock according to the
1279 * configuration.
1280 *
1281 * @param config Pointer to the configuration structure.
1282 * @retval kStatus_Success SIRC is initialized.
1283 * @retval kStatus_SCG_Busy SIRC has been enabled and is used by system clock.
1284 * @retval kStatus_ReadOnly SIRC control register is locked.
1285 *
1286 * @note This function can't detect whether the system OSC has been enabled and
1287 * used by an IP.
1288 */
1289status_t CLOCK_InitSirc(const scg_sirc_config_t *config);
1290
1291/*!
1292 * @brief De-initializes the SCG slow IRC.
1293 *
1294 * This function disables the SCG slow IRC.
1295 *
1296 * @retval kStatus_Success SIRC is deinitialized.
1297 * @retval kStatus_SCG_Busy SIRC is used by system clock.
1298 * @retval kStatus_ReadOnly SIRC control register is locked.
1299 *
1300 * @note This function can't detect whether the SIRC is used by an IP.
1301 */
1302status_t CLOCK_DeinitSirc(void);
1303
1304/*!
1305 * @brief Set the asynchronous clock divider.
1306 *
1307 * @param asyncClk Which asynchronous clock to configure.
1308 * @param divider The divider value to set.
1309 *
1310 * @note There might be glitch when changing the asynchronous divider, so make sure
1311 * the asynchronous clock is not used while changing divider.
1312 */
1313static inline void CLOCK_SetSircAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
1314{
1315 uint32_t reg = SCG->SIRCDIV;
1316
1317 switch (asyncClk)
1318 {
1319 case kSCG_AsyncDiv3Clk:
1320 reg = (reg & ~SCG_SIRCDIV_SIRCDIV3_MASK) | SCG_SIRCDIV_SIRCDIV3(divider);
1321 break;
1322 case kSCG_AsyncDiv2Clk:
1323 reg = (reg & ~SCG_SIRCDIV_SIRCDIV2_MASK) | SCG_SIRCDIV_SIRCDIV2(divider);
1324 break;
1325 default:
1326 reg = (reg & ~SCG_SIRCDIV_SIRCDIV1_MASK) | SCG_SIRCDIV_SIRCDIV1(divider);
1327 break;
1328 }
1329
1330 SCG->SIRCDIV = reg;
1331}
1332
1333/*!
1334 * @brief Enables/disables the SCG slow IRC 1khz LPO clock in LLS/VLLSx modes.
1335 *
1336 * This function enables/disables the SCG slow IRC 1khz LPO clock in LLS/VLLSx modes.
1337 *
1338 * @param enable Switcher of LPO Power Option which controls whether the 1 kHz LPO clock is enabled in LLS/VLLSx
1339 * modes.
1340 * "true" means to enable, "false" means not enabled.
1341 */
1342static inline void CLOCK_EnableLpoPowerOption(bool enable)
1343{
1344 if (enable)
1345 {
1346 SCG->SIRCCSR &= ~SCG_SIRCCSR_LPOPO_MASK;
1347 }
1348 else
1349 {
1350 SCG->SIRCCSR |= SCG_SIRCCSR_LPOPO_MASK;
1351 }
1352}
1353
1354/*!
1355 * @brief Gets the SCG SIRC clock frequency.
1356 *
1357 * @return Clock frequency; If the clock is invalid, returns 0.
1358 */
1359uint32_t CLOCK_GetSircFreq(void);
1360
1361/*!
1362 * @brief Gets the SCG asynchronous clock frequency from the SIRC.
1363 *
1364 * @param type The asynchronous clock type.
1365 * @return Clock frequency; If the clock is invalid, returns 0.
1366 */
1367uint32_t CLOCK_GetSircAsyncFreq(scg_async_clk_t type);
1368
1369/*!
1370 * @brief Checks whether the SIRC clock is valid.
1371 *
1372 * @return True if clock is valid, false if not.
1373 */
1374static inline bool CLOCK_IsSircValid(void)
1375{
1376 return ((SCG->SIRCCSR & SCG_SIRCCSR_SIRCVLD_MASK) == SCG_SIRCCSR_SIRCVLD_MASK);
1377}
1378/* @} */
1379
1380/*!
1381 * @name SCG Fast IRC Clock.
1382 * @{
1383 */
1384
1385/*!
1386 * @brief Initializes the SCG fast IRC clock.
1387 *
1388 * This function enables the SCG fast IRC clock according to the configuration.
1389 *
1390 * @param config Pointer to the configuration structure.
1391 * @retval kStatus_Success FIRC is initialized.
1392 * @retval kStatus_SCG_Busy FIRC has been enabled and is used by the system clock.
1393 * @retval kStatus_ReadOnly FIRC control register is locked.
1394 *
1395 * @note This function can't detect whether the FIRC has been enabled and
1396 * used by an IP.
1397 */
1398status_t CLOCK_InitFirc(const scg_firc_config_t *config);
1399
1400/*!
1401 * @brief De-initializes the SCG fast IRC.
1402 *
1403 * This function disables the SCG fast IRC.
1404 *
1405 * @retval kStatus_Success FIRC is deinitialized.
1406 * @retval kStatus_SCG_Busy FIRC is used by the system clock.
1407 * @retval kStatus_ReadOnly FIRC control register is locked.
1408 *
1409 * @note This function can't detect whether the FIRC is used by an IP.
1410 */
1411status_t CLOCK_DeinitFirc(void);
1412
1413/*!
1414 * @brief Set the asynchronous clock divider.
1415 *
1416 * @param asyncClk Which asynchronous clock to configure.
1417 * @param divider The divider value to set.
1418 *
1419 * @note There might be glitch when changing the asynchronous divider, so make sure
1420 * the asynchronous clock is not used while changing divider.
1421 */
1422static inline void CLOCK_SetFircAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
1423{
1424 uint32_t reg = SCG->FIRCDIV;
1425
1426 switch (asyncClk)
1427 {
1428 case kSCG_AsyncDiv3Clk:
1429 reg = (reg & ~SCG_FIRCDIV_FIRCDIV3_MASK) | SCG_FIRCDIV_FIRCDIV3(divider);
1430 break;
1431 case kSCG_AsyncDiv2Clk:
1432 reg = (reg & ~SCG_FIRCDIV_FIRCDIV2_MASK) | SCG_FIRCDIV_FIRCDIV2(divider);
1433 break;
1434 default:
1435 reg = (reg & ~SCG_FIRCDIV_FIRCDIV1_MASK) | SCG_FIRCDIV_FIRCDIV1(divider);
1436 break;
1437 }
1438
1439 SCG->FIRCDIV = reg;
1440}
1441
1442/*!
1443 * @brief Gets the SCG FIRC clock frequency.
1444 *
1445 * @return Clock frequency; If the clock is invalid, returns 0.
1446 */
1447uint32_t CLOCK_GetFircFreq(void);
1448
1449/*!
1450 * @brief Gets the SCG asynchronous clock frequency from the FIRC.
1451 *
1452 * @param type The asynchronous clock type.
1453 * @return Clock frequency; If the clock is invalid, returns 0.
1454 */
1455uint32_t CLOCK_GetFircAsyncFreq(scg_async_clk_t type);
1456
1457/*!
1458 * @brief Checks whether the FIRC clock error occurs.
1459 *
1460 * @return True if the error occurs, false if not.
1461 */
1462static inline bool CLOCK_IsFircErr(void)
1463{
1464 return ((SCG->FIRCCSR & SCG_FIRCCSR_FIRCERR_MASK) == SCG_FIRCCSR_FIRCERR_MASK);
1465}
1466
1467/*!
1468 * @brief Clears the FIRC clock error.
1469 */
1470static inline void CLOCK_ClearFircErr(void)
1471{
1472 SCG->FIRCCSR |= SCG_FIRCCSR_FIRCERR_MASK;
1473}
1474
1475/*!
1476 * @brief Checks whether the FIRC clock is valid.
1477 *
1478 * @return True if clock is valid, false if not.
1479 */
1480static inline bool CLOCK_IsFircValid(void)
1481{
1482 return ((SCG->FIRCCSR & SCG_FIRCCSR_FIRCVLD_MASK) == SCG_FIRCCSR_FIRCVLD_MASK);
1483}
1484/* @} */
1485
1486/*!
1487 * @brief Gets the SCG RTC OSC clock frequency.
1488 *
1489 * @return Clock frequency; If the clock is invalid, returns 0.
1490 */
1491uint32_t CLOCK_GetRtcOscFreq(void);
1492
1493/*!
1494 * @brief Checks whether the RTC OSC clock error occurs.
1495 *
1496 * @return True if error occurs, false if not.
1497 */
1498static inline bool CLOCK_IsRtcOscErr(void)
1499{
1500 return ((SCG->ROSCCSR & SCG_ROSCCSR_ROSCERR_MASK) == SCG_ROSCCSR_ROSCERR_MASK);
1501}
1502
1503/*!
1504 * @brief Clears the RTC OSC clock error.
1505 */
1506static inline void CLOCK_ClearRtcOscErr(void)
1507{
1508 SCG->ROSCCSR |= SCG_ROSCCSR_ROSCERR_MASK;
1509}
1510
1511/*!
1512 * @brief Sets the RTC OSC monitor mode.
1513 *
1514 * This function sets the RTC OSC monitor mode. The mode can be disabled.
1515 * It can generate an interrupt when the error is disabled, or reset when the error is detected.
1516 *
1517 * @param mode Monitor mode to set.
1518 */
1519static inline void CLOCK_SetRtcOscMonitorMode(scg_rosc_monitor_mode_t mode)
1520{
1521 uint32_t reg = SCG->ROSCCSR;
1522
1523 reg &= ~(SCG_ROSCCSR_ROSCCM_MASK | SCG_ROSCCSR_ROSCCMRE_MASK);
1524
1525 reg |= (uint32_t)mode;
1526
1527 SCG->ROSCCSR = reg;
1528}
1529
1530/*!
1531 * @brief Checks whether the RTC OSC clock is valid.
1532 *
1533 * @return True if the clock is valid, false if not.
1534 */
1535static inline bool CLOCK_IsRtcOscValid(void)
1536{
1537 return ((SCG->ROSCCSR & SCG_ROSCCSR_ROSCVLD_MASK) == SCG_ROSCCSR_ROSCVLD_MASK);
1538}
1539/* @} */
1540
1541/* @} */
1542/*!
1543 * @brief Initializes the SCG auxiliary PLL.
1544 *
1545 * This function enables the SCG auxiliary PLL clock according to the
1546 * configuration. The auxiliary PLL can use the system OSC or FIRC as
1547 * the clock source. Ensure that the source clock is valid before
1548 * calling this function.
1549 *
1550 * Example code for initializing APLL clock output:
1551 * @code
1552 * const scg_apll_config_t g_scgAuxPllConfig = {.enableMode = kSCG_AuxPllEnable,
1553 * .div1 = kSCG_AsyncClkDisable,
1554 * .div2 = kSCG_AsyncClkDisable,
1555 * .div3 = kSCG_AsyncClkDisable,
1556 * .src = kSCG_SysPllSrcFirc,
1557 * .isPfdSelected = false,
1558 * .prediv = 5U,
1559 * .pfdClkout = kSCG_AuxPllPfd0Clk,
1560 * .mult = 20U,
1561 * .pllPostdiv1 = kSCG_SysClkDivBy3,
1562 * .pllPostdiv2 = kSCG_SysClkDivBy4,
1563 * .num = 578,
1564 * .denom = 1000};
1565 * CLOCK_InitAuxPll(&g_scgAuxPllConfig);
1566 * @endcode
1567 *
1568 * @param config Pointer to the configuration structure.
1569 * @retval kStatus_Success auxiliary PLL is initialized.
1570 * @retval kStatus_SCG_Busy auxiliary PLL has been enabled and is used by the system clock.
1571 * @retval kStatus_ReadOnly auxiliary PLL control register is locked.
1572 *
1573 * @note This function can't detect whether the auxiliary PLL has been enabled and
1574 * is used by an IP.
1575 */
1576status_t CLOCK_InitAuxPll(const scg_apll_config_t *config);
1577
1578/*!
1579 * @brief De-initializes the SCG auxiliary PLL.
1580 *
1581 * This function disables the SCG auxiliary PLL.
1582 *
1583 * @retval kStatus_Success auxiliary PLL is deinitialized.
1584 * @retval kStatus_SCG_Busy auxiliary PLL is used by the system clock.
1585 * @retval kStatus_ReadOnly auxiliary PLL control register is locked.
1586 *
1587 * @note This function can't detect whether the auxiliary PLL is used by an IP.
1588 */
1589status_t CLOCK_DeinitAuxPll(void);
1590
1591/*!
1592 * @brief Set the asynchronous clock divider.
1593 *
1594 * @param asyncClk Which asynchronous clock to configure.
1595 * @param divider The divider value to set.
1596 *
1597 * @note There might be glitch when changing the asynchronous divider, so make sure
1598 * the asynchronous clock is not used while changing divider.
1599 */
1600static inline void CLOCK_SetAuxPllAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
1601{
1602 uint32_t reg = SCG->APLLDIV;
1603
1604 switch (asyncClk)
1605 {
1606 case kSCG_AsyncDiv1Clk:
1607 reg = (reg & ~SCG_APLLDIV_APLLDIV1_MASK) | SCG_APLLDIV_APLLDIV1(divider);
1608 break;
1609 case kSCG_AsyncDiv2Clk:
1610 reg = (reg & ~SCG_APLLDIV_APLLDIV2_MASK) | SCG_APLLDIV_APLLDIV2(divider);
1611 break;
1612 default:
1613 reg = (reg & ~SCG_APLLDIV_APLLDIV1_MASK) | SCG_APLLDIV_APLLDIV1(divider);
1614 break;
1615 }
1616
1617 SCG->APLLDIV = reg;
1618}
1619
1620/*!
1621 * @brief Gets the SCG auxiliary PLL clock frequency.
1622 *
1623 * @return Clock frequency; If the clock is invalid, returns 0.
1624 */
1625uint32_t CLOCK_GetAuxPllFreq(void);
1626
1627/*!
1628 * @brief Gets the SCG asynchronous clock frequency from the auxiliary PLL.
1629 *
1630 * @param type The asynchronous clock type.
1631 * @return Clock frequency; If the clock is invalid, returns 0.
1632 */
1633uint32_t CLOCK_GetAuxPllAsyncFreq(scg_async_clk_t type);
1634
1635/*!
1636 * @brief Gets the SCG auxiliary PLL PFD clock frequency.
1637 *
1638 * @param pfdClkout The selected PFD clocks out. See "scg_apll_pfd_clkout_t".
1639 * @return Clock frequency; If the clock is invalid, returns 0.
1640 */
1641uint32_t CLOCK_GetAuxPllPfdFreq(scg_apll_pfd_clkout_t pfdClkout);
1642
1643/*!
1644 * @brief Enables the SCG auxiliary PLL Fractional Divide (PFD) clock out with configurations.
1645 *
1646 * APLL Frequency = Fref * (MULT + NUM/DENOM)
1647 * PFD Clock Frequency = PLL output frequency * 18/frac value
1648 *
1649 * Example code for configuring APLL as APLL PFD clock output:
1650 * @code
1651 * const scg_apll_config_t g_scgAuxPllConfig = {.enableMode = kSCG_AuxPllEnable,
1652 * .div1 = kSCG_AsyncClkDisable,
1653 * .div2 = kSCG_AsyncClkDisable,
1654 * .div3 = kSCG_AsyncClkDisable,
1655 * .src = kSCG_SysPllSrcFirc,
1656 * .isPfdSelected = true,
1657 * .prediv = 5U,
1658 * .pfdClkout = kSCG_AuxPllPfd3Clk,
1659 * clock
1660 * .mult = 20U,
1661 * .pllPostdiv1 = kSCG_SysClkDivBy1,
1662 * .pllPostdiv2 = kSCG_SysClkDivBy1,
1663 * .num = 578,
1664 * .denom = 1000};
1665 * CLOCK_InitAuxPll(&g_scgAuxPllConfig);
1666 * CLOCK_EnableAuxPllPfdClkout(g_scgAuxPllConfig.pfdClkout, 15U);
1667 * @endcode
1668 *
1669 * @param pfdClkout APLL PFD clock out select.
1670 * @param fracValue Fractional Divider value. Recommended to be kept between 12-35 for all PFDs.
1671 */
1672void CLOCK_EnableAuxPllPfdClkout(scg_apll_pfd_clkout_t pfdClkout, uint8_t fracValue);
1673
1674/*!
1675 * @brief Disables the SCG auxiliary PLL Fractional Divide (PFD) clock out.
1676 */
1677static inline void CLOCK_DisableAuxPllPfdClkout(scg_apll_pfd_clkout_t pfdClkout)
1678{
1679 SCG->APLLPFD |= SCG_PLLPFD_PFD_CLKGATE_MASK(pfdClkout);
1680}
1681
1682/*!
1683 * @brief Enables the SCG auxiliary PLL spread spectrum modulation feature with configurations.
1684 *
1685 * This function sets the SCG auxiliary PLL spread spectrum modulation configurations.
1686 * STOP and STEP together control the modulation depth (maximum frequency change)
1687 * and modulation frequency.
1688 *
1689 * Modulation Depth = (STOP/MFD)*Fref where MFD is the DENOM field value in DENOM register.
1690 * Modulation Frequency = (STEP/(2*STOP))*Fref.
1691 *
1692 * @param step APLL Spread Spectrum STEP.
1693 * @param stop APLL Spread Spectrum STOP.
1694 */
1695static inline void CLOCK_EnableAuxPllSpectrumModulation(uint16_t step, uint16_t stop)
1696{
1697 SCG->APLLSS = (SCG->APLLSS & ~(SCG_APLLSS_STEP_MASK | SCG_APLLSS_STOP_MASK)) |
1698 (SCG_APLLSS_STEP(step) | SCG_APLLSS_STOP(stop) | SCG_APLLSS_ENABLE_MASK);
1699}
1700
1701/*!
1702 * @brief Disables the SCG auxiliary PLL spread spectrum modulation.
1703 *
1704 */
1705static inline void CLOCK_DisableAuxPllSpectrumModulation(void)
1706{
1707 SCG->APLLSS &= ~SCG_APLLSS_ENABLE_MASK;
1708}
1709
1710/*!
1711 * @brief Sets the SCG auxiliary PLL lock time.
1712 *
1713 * @param lockTime Reference clocks to count before APLL is considered locked and valid.
1714 */
1715static inline void CLOCK_SetAuxPllLockTime(uint16_t lockTime)
1716{
1717 SCG->APLLLOCK_CNFG = SCG_APLLLOCK_CNFG_LOCK_TIME(lockTime);
1718}
1719
1720/*!
1721 * @brief Checks whether the auxiliary PLL clock is valid.
1722 *
1723 * @return True if the clock is valid, false if not.
1724 */
1725static inline bool CLOCK_IsAuxPllValid(void)
1726{
1727 return ((SCG->APLLCSR & SCG_APLLCSR_APLLVLD_MASK) == SCG_APLLCSR_APLLVLD_MASK);
1728}
1729/* @} */
1730
1731/*!
1732 * @brief Initializes the SCG system PLL.
1733 *
1734 * This function enables the SCG system PLL clock according to the
1735 * configuration. The system PLL can use the system OSC or FIRC as
1736 * the clock source. Ensure that the source clock is valid before
1737 * calling this function.
1738 *
1739 * Example code for initializing SPLL clock output:
1740 * @code
1741 * const scg_spll_config_t g_scgSysPllConfig = {.enableMode = kSCG_SysPllEnable,
1742 * .div1 = kSCG_AsyncClkDivBy1,
1743 * .div2 = kSCG_AsyncClkDisable,
1744 * .div3 = kSCG_AsyncClkDivBy2,
1745 * .src = kSCG_SysPllSrcFirc,
1746 * .isPfdSelected = false,
1747 * .prediv = 0U,
1748 * .pfdClkout = kSCG_SysPllPfd0Clk,
1749 * .mult = 3U};
1750 * CLOCK_InitSysPll(&g_scgSysPllConfig);
1751 * @endcode
1752 *
1753 * @param config Pointer to the configuration structure.
1754 * @retval kStatus_Success System PLL is initialized.
1755 * @retval kStatus_SCG_Busy System PLL has been enabled and is used by the system clock.
1756 * @retval kStatus_ReadOnly System PLL control register is locked.
1757 *
1758 * @note This function can't detect whether the system PLL has been enabled and
1759 * used by an IP.
1760 */
1761status_t CLOCK_InitSysPll(const scg_spll_config_t *config);
1762
1763/*!
1764 * @brief De-initializes the SCG system PLL.
1765 *
1766 * This function disables the SCG system PLL.
1767 *
1768 * @retval kStatus_Success system PLL is deinitialized.
1769 * @retval kStatus_SCG_Busy system PLL is used by the system clock.
1770 * @retval kStatus_ReadOnly System PLL control register is locked.
1771 *
1772 * @note This function can't detect whether the system PLL is used by an IP.
1773 */
1774status_t CLOCK_DeinitSysPll(void);
1775
1776/*!
1777 * @brief Set the asynchronous clock divider.
1778 *
1779 * @param asyncClk Which asynchronous clock to configure.
1780 * @param divider The divider value to set.
1781 *
1782 * @note There might be glitch when changing the asynchronous divider, so make sure
1783 * the asynchronous clock is not used while changing divider.
1784 */
1785static inline void CLOCK_SetSysPllAsyncClkDiv(scg_async_clk_t asyncClk, scg_async_clk_div_t divider)
1786{
1787 uint32_t reg = SCG->SPLLDIV;
1788
1789 switch (asyncClk)
1790 {
1791 case kSCG_AsyncDiv3Clk:
1792 reg = (reg & ~SCG_SPLLDIV_SPLLDIV3_MASK) | SCG_SPLLDIV_SPLLDIV3(divider);
1793 break;
1794 case kSCG_AsyncDiv2Clk:
1795 reg = (reg & ~SCG_SPLLDIV_SPLLDIV2_MASK) | SCG_SPLLDIV_SPLLDIV2(divider);
1796 break;
1797 default:
1798 reg = (reg & ~SCG_SPLLDIV_SPLLDIV1_MASK) | SCG_SPLLDIV_SPLLDIV1(divider);
1799 break;
1800 }
1801
1802 SCG->SPLLDIV = reg;
1803}
1804
1805/*!
1806 * @brief Gets the SCG system PLL clock frequency.
1807 *
1808 * @return Clock frequency; If the clock is invalid, returns 0.
1809 */
1810uint32_t CLOCK_GetSysPllFreq(void);
1811
1812/*!
1813 * @brief Gets the SCG asynchronous clock frequency from the system PLL.
1814 *
1815 * @param type The asynchronous clock type.
1816 * @return Clock frequency; If the clock is invalid, returns 0.
1817 */
1818uint32_t CLOCK_GetSysPllAsyncFreq(scg_async_clk_t type);
1819
1820/*!
1821 * @brief Gets the SCG system PLL PFD clock frequency.
1822 *
1823 * @param pfdClkout The selected PFD clock out. See "scg_spll_pfd_clkout_t".
1824 * @return Clock frequency; If the clock is invalid, returns 0.
1825 */
1826uint32_t CLOCK_GetSysPllPfdFreq(scg_spll_pfd_clkout_t pfdClkout);
1827
1828/*!
1829 * @brief Enables the SCG system PLL Fractional Divide (PFD) clock out with configurations.
1830 *
1831 * SPLL Frequency = Fref * (MULT + NUM/DENOM)
1832 * PFD Clock Frequency = PLL output frequency * 18/frac value
1833 *
1834 * @code
1835 * Example code for configuring SPLL as SPLL PFD clock output:
1836 * const scg_spll_config_t g_scgSysPllConfig = {.enableMode = kSCG_SysPllEnable,
1837 * .div1 = kSCG_AsyncClkDisable,
1838 * .div2 = kSCG_AsyncClkDisable,
1839 * .div3 = kSCG_AsyncClkDisable,
1840 * .src = kSCG_SysPllSrcFirc,
1841 * .isPfdSelected = true,
1842 * .prediv = 5U,
1843 * .pfdClkout = kSCG_AuxPllPfd3Clk,
1844 * clock
1845 * .mult = 20U};
1846 * CLOCK_InitSysPll(&g_scgSysPllConfig);
1847 * CLOCK_EnableSysPllPfdClkout(g_scgSysPllConfig.pfdClkout, 15U);
1848 * @endcode
1849 *
1850 * @param pfdClkout SPLL PFD clock out select.
1851 * @param fracValue Fractional Divider value. Recommended to be kept between 12-35 for all PFDs.
1852 */
1853void CLOCK_EnableSysPllPfdClkout(scg_spll_pfd_clkout_t pfdClkout, uint8_t fracValue);
1854
1855/*!
1856 * @brief Disables the SCG system PLL Fractional Divide (PFD) clock out.
1857 */
1858static inline void CLOCK_DisableSysPllPfdClkout(scg_spll_pfd_clkout_t pfdClkout)
1859{
1860 SCG->SPLLPFD |= SCG_PLLPFD_PFD_CLKGATE_MASK(pfdClkout);
1861}
1862
1863/*!
1864 * @brief Checks whether the system PLL clock error occurs.
1865 *
1866 * @return True if an error occurs, false if not.
1867 */
1868static inline bool CLOCK_IsSysPllErr(void)
1869{
1870 return ((SCG->SPLLCSR & SCG_SPLLCSR_SPLLERR_MASK) == SCG_SPLLCSR_SPLLERR_MASK);
1871}
1872
1873/*!
1874 * @brief Clears the system PLL clock error.
1875 */
1876static inline void CLOCK_ClearSysPllErr(void)
1877{
1878 SCG->SPLLCSR |= SCG_SPLLCSR_SPLLERR_MASK;
1879}
1880
1881/*!
1882 * @brief Checks whether the system PLL clock is valid.
1883 *
1884 * @return True if the clock is valid, false if not.
1885 */
1886static inline bool CLOCK_IsSysPllValid(void)
1887{
1888 return ((SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK) == SCG_SPLLCSR_SPLLVLD_MASK);
1889}
1890/* @} */
1891
1892/*!
1893 * @name External clock frequency
1894 * @{
1895 */
1896
1897/*!
1898 * @brief Sets the XTAL0 frequency based on board settings.
1899 *
1900 * @param freq The XTAL0/EXTAL0 input clock frequency in Hz.
1901 */
1902static inline void CLOCK_SetXtal0Freq(uint32_t freq)
1903{
1904 g_xtal0Freq = freq;
1905}
1906
1907/*!
1908 * @brief Sets the XTAL32 frequency based on board settings.
1909 *
1910 * @param freq The XTAL32/EXTAL32 input clock frequency in Hz.
1911 */
1912static inline void CLOCK_SetXtal32Freq(uint32_t freq)
1913{
1914 g_xtal32Freq = freq;
1915}
1916
1917/*!
1918 * @brief Sets the LVDS pad frequency based on board settings.
1919 *
1920 * @param freq The LVDS pad input clock frequency in Hz.
1921 */
1922static inline void CLOCK_SetLvdsFreq(uint32_t freq)
1923{
1924 g_lvdsFreq = freq;
1925}
1926
1927/* @} */
1928
1929#if defined(__cplusplus)
1930}
1931#endif /* __cplusplus */
1932
1933/*! @} */
1934
1935#endif /* _FSL_CLOCK_H_ */