1 /*
2  * Copyright 2020, 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 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "platform.drivers.clock"
16 #endif
17 
18 #define CGC_SOSCDIV_DIV1_VAL(reg)                                       \
19     (((((reg)&CGC_SOSCDIV_DIV1_MASK) >> CGC_SOSCDIV_DIV1_SHIFT) + 1U) * \
20      ((((reg)&CGC_SOSCDIV_DIV1HALT_MASK) >> CGC_SOSCDIV_DIV1HALT_SHIFT) ^ 1U))
21 #define CGC_SOSCDIV_DIV2_VAL(reg)                                       \
22     (((((reg)&CGC_SOSCDIV_DIV2_MASK) >> CGC_SOSCDIV_DIV2_SHIFT) + 1U) * \
23      ((((reg)&CGC_SOSCDIV_DIV2HALT_MASK) >> CGC_SOSCDIV_DIV2HALT_SHIFT) ^ 1U))
24 #define CGC_SOSCDIV_DIV3_VAL(reg)                                       \
25     (((((reg)&CGC_SOSCDIV_DIV3_MASK) >> CGC_SOSCDIV_DIV3_SHIFT) + 1U) * \
26      ((((reg)&CGC_SOSCDIV_DIV3HALT_MASK) >> CGC_SOSCDIV_DIV3HALT_SHIFT) ^ 1U))
27 #define CGC_FRODIV_DIV1_VAL(reg)                                      \
28     (((((reg)&CGC_FRODIV_DIV1_MASK) >> CGC_FRODIV_DIV1_SHIFT) + 1U) * \
29      ((((reg)&CGC_FRODIV_DIV1HALT_MASK) >> CGC_FRODIV_DIV1HALT_SHIFT) ^ 1U))
30 #define CGC_FRODIV_DIV2_VAL(reg)                                      \
31     (((((reg)&CGC_FRODIV_DIV2_MASK) >> CGC_FRODIV_DIV2_SHIFT) + 1U) * \
32      ((((reg)&CGC_FRODIV_DIV2HALT_MASK) >> CGC_FRODIV_DIV2HALT_SHIFT) ^ 1U))
33 #define CGC_FRODIV_DIV3_VAL(reg)                                      \
34     (((((reg)&CGC_FRODIV_DIV3_MASK) >> CGC_FRODIV_DIV3_SHIFT) + 1U) * \
35      ((((reg)&CGC_FRODIV_DIV3HALT_MASK) >> CGC_FRODIV_DIV3HALT_SHIFT) ^ 1U))
36 
37 #define CGC_PLL0DIV_VCO_DIV1_VAL                                                                 \
38     ((((CGC_RTD->PLL0DIV_VCO & CGC_PLL0DIV_VCO_DIV1_MASK) >> CGC_PLL0DIV_VCO_DIV1_SHIFT) + 1U) * \
39      (((CGC_RTD->PLL0DIV_VCO & CGC_PLL0DIV_VCO_DIV1HALT_MASK) >> CGC_PLL0DIV_VCO_DIV1HALT_SHIFT) ^ 1U))
40 #define CGC_PLL0DIV_PFD1_DIV_VAL                                                                       \
41     ((((CGC_RTD->PLL0DIV_PFD_0 & CGC_PLL0DIV_PFD_0_DIV1_MASK) >> CGC_PLL0DIV_PFD_0_DIV1_SHIFT) + 1U) * \
42      (((CGC_RTD->PLL0DIV_PFD_0 & CGC_PLL0DIV_PFD_0_DIV1HALT_MASK) >> CGC_PLL0DIV_PFD_0_DIV1HALT_SHIFT) ^ 1U))
43 #define CGC_PLL0DIV_PFD2_DIV_VAL                                                                       \
44     ((((CGC_RTD->PLL0DIV_PFD_0 & CGC_PLL0DIV_PFD_0_DIV2_MASK) >> CGC_PLL0DIV_PFD_0_DIV2_SHIFT) + 1U) * \
45      (((CGC_RTD->PLL0DIV_PFD_0 & CGC_PLL0DIV_PFD_0_DIV2HALT_MASK) >> CGC_PLL0DIV_PFD_0_DIV2HALT_SHIFT) ^ 1U))
46 
47 #define CGC_PLL1DIV_VCO_DIV1_VAL                                                                 \
48     ((((CGC_RTD->PLL1DIV_VCO & CGC_PLL1DIV_VCO_DIV1_MASK) >> CGC_PLL1DIV_VCO_DIV1_SHIFT) + 1U) * \
49      (((CGC_RTD->PLL1DIV_VCO & CGC_PLL1DIV_VCO_DIV1HALT_MASK) >> CGC_PLL1DIV_VCO_DIV1HALT_SHIFT) ^ 1U))
50 #define CGC_PLL1DIV_PFD1_DIV_VAL                                                                       \
51     ((((CGC_RTD->PLL1DIV_PFD_0 & CGC_PLL1DIV_PFD_0_DIV1_MASK) >> CGC_PLL1DIV_PFD_0_DIV1_SHIFT) + 1U) * \
52      (((CGC_RTD->PLL1DIV_PFD_0 & CGC_PLL1DIV_PFD_0_DIV1HALT_MASK) >> CGC_PLL1DIV_PFD_0_DIV1HALT_SHIFT) ^ 1U))
53 #define CGC_PLL1DIV_PFD2_DIV_VAL                                                                       \
54     ((((CGC_RTD->PLL1DIV_PFD_0 & CGC_PLL1DIV_PFD_0_DIV2_MASK) >> CGC_PLL1DIV_PFD_0_DIV2_SHIFT) + 1U) * \
55      (((CGC_RTD->PLL1DIV_PFD_0 & CGC_PLL1DIV_PFD_0_DIV2HALT_MASK) >> CGC_PLL1DIV_PFD_0_DIV2HALT_SHIFT) ^ 1U))
56 
57 #define CGC_AD_PLL3DIV_VCO_DIV1_VAL                                                                   \
58     ((((CGC_AD->PLL3DIV_VCO & CGC_AD_PLL3DIV_VCO_DIV1_MASK) >> CGC_AD_PLL3DIV_VCO_DIV1_SHIFT) + 1U) * \
59      (((CGC_AD->PLL3DIV_VCO & CGC_AD_PLL3DIV_VCO_DIV1HALT_MASK) >> CGC_AD_PLL3DIV_VCO_DIV1HALT_SHIFT) ^ 1U))
60 #define CGC_AD_PLL3DIV_PFD0_DIV1_VAL                                                                        \
61     ((((CGC_AD->PLL3DIV_PFD_0 & CGC_AD_PLL3DIV_PFD_0_DIV1_MASK) >> CGC_AD_PLL3DIV_PFD_0_DIV1_SHIFT) + 1U) * \
62      (((CGC_AD->PLL3DIV_PFD_0 & CGC_AD_PLL3DIV_PFD_0_DIV1HALT_MASK) >> CGC_AD_PLL3DIV_PFD_0_DIV1HALT_SHIFT) ^ 1U))
63 #define CGC_AD_PLL3DIV_PFD0_DIV2_VAL                                                                        \
64     ((((CGC_AD->PLL3DIV_PFD_0 & CGC_AD_PLL3DIV_PFD_0_DIV2_MASK) >> CGC_AD_PLL3DIV_PFD_0_DIV2_SHIFT) + 1U) * \
65      (((CGC_AD->PLL3DIV_PFD_0 & CGC_AD_PLL3DIV_PFD_0_DIV2HALT_MASK) >> CGC_AD_PLL3DIV_PFD_0_DIV2HALT_SHIFT) ^ 1U))
66 #define CGC_AD_PLL3DIV_PFD1_DIV1_VAL                                                                        \
67     ((((CGC_AD->PLL3DIV_PFD_0 & CGC_AD_PLL3DIV_PFD_0_DIV3_MASK) >> CGC_AD_PLL3DIV_PFD_0_DIV3_SHIFT) + 1U) * \
68      (((CGC_AD->PLL3DIV_PFD_0 & CGC_AD_PLL3DIV_PFD_0_DIV3HALT_MASK) >> CGC_AD_PLL3DIV_PFD_0_DIV3HALT_SHIFT) ^ 1U))
69 #define CGC_AD_PLL3DIV_PFD1_DIV2_VAL                                                                        \
70     ((((CGC_AD->PLL3DIV_PFD_0 & CGC_AD_PLL3DIV_PFD_0_DIV4_MASK) >> CGC_AD_PLL3DIV_PFD_0_DIV4_SHIFT) + 1U) * \
71      (((CGC_AD->PLL3DIV_PFD_0 & CGC_AD_PLL3DIV_PFD_0_DIV4HALT_MASK) >> CGC_AD_PLL3DIV_PFD_0_DIV4HALT_SHIFT) ^ 1U))
72 #define CGC_AD_PLL3DIV_PFD2_DIV1_VAL                                                                        \
73     ((((CGC_AD->PLL3DIV_PFD_1 & CGC_AD_PLL3DIV_PFD_1_DIV1_MASK) >> CGC_AD_PLL3DIV_PFD_1_DIV1_SHIFT) + 1U) * \
74      (((CGC_AD->PLL3DIV_PFD_1 & CGC_AD_PLL3DIV_PFD_1_DIV1HALT_MASK) >> CGC_AD_PLL3DIV_PFD_1_DIV1HALT_SHIFT) ^ 1U))
75 #define CGC_AD_PLL3DIV_PFD2_DIV2_VAL                                                                        \
76     ((((CGC_AD->PLL3DIV_PFD_1 & CGC_AD_PLL3DIV_PFD_1_DIV2_MASK) >> CGC_AD_PLL3DIV_PFD_1_DIV2_SHIFT) + 1U) * \
77      (((CGC_AD->PLL3DIV_PFD_1 & CGC_AD_PLL3DIV_PFD_1_DIV2HALT_MASK) >> CGC_AD_PLL3DIV_PFD_1_DIV2HALT_SHIFT) ^ 1U))
78 #define CGC_AD_PLL3DIV_PFD3_DIV1_VAL                                                                        \
79     ((((CGC_AD->PLL3DIV_PFD_1 & CGC_AD_PLL3DIV_PFD_1_DIV3_MASK) >> CGC_AD_PLL3DIV_PFD_1_DIV3_SHIFT) + 1U) * \
80      (((CGC_AD->PLL3DIV_PFD_1 & CGC_AD_PLL3DIV_PFD_1_DIV3HALT_MASK) >> CGC_AD_PLL3DIV_PFD_1_DIV3HALT_SHIFT) ^ 1U))
81 #define CGC_AD_PLL3DIV_PFD3_DIV2_VAL                                                                        \
82     ((((CGC_AD->PLL3DIV_PFD_1 & CGC_AD_PLL3DIV_PFD_1_DIV4_MASK) >> CGC_AD_PLL3DIV_PFD_1_DIV4_SHIFT) + 1U) * \
83      (((CGC_AD->PLL3DIV_PFD_1 & CGC_AD_PLL3DIV_PFD_1_DIV4HALT_MASK) >> CGC_AD_PLL3DIV_PFD_1_DIV4HALT_SHIFT) ^ 1U))
84 
85 #define CGC_LPAV_PLL4DIV_VCO_DIV1_VAL                                                                       \
86     ((((CGC_LPAV->PLL4DIV_VCO & CGC_LPAV_PLL4DIV_VCO_DIV1_MASK) >> CGC_LPAV_PLL4DIV_VCO_DIV1_SHIFT) + 1U) * \
87      (((CGC_LPAV->PLL4DIV_VCO & CGC_LPAV_PLL4DIV_VCO_DIV1HALT_MASK) >> CGC_LPAV_PLL4DIV_VCO_DIV1HALT_SHIFT) ^ 1U))
88 #define CGC_LPAV_PLL4DIV_PFD0_DIV1_VAL                                                                              \
89     ((((CGC_LPAV->PLL4DIV_PFD_0 & CGC_LPAV_PLL4DIV_PFD_0_DIV1_MASK) >> CGC_LPAV_PLL4DIV_PFD_0_DIV1_SHIFT) + 1U) *   \
90      (((CGC_LPAV->PLL4DIV_PFD_0 & CGC_LPAV_PLL4DIV_PFD_0_DIV1HALT_MASK) >> CGC_LPAV_PLL4DIV_PFD_0_DIV1HALT_SHIFT) ^ \
91       1U))
92 #define CGC_LPAV_PLL4DIV_PFD0_DIV2_VAL                                                                              \
93     ((((CGC_LPAV->PLL4DIV_PFD_0 & CGC_LPAV_PLL4DIV_PFD_0_DIV2_MASK) >> CGC_LPAV_PLL4DIV_PFD_0_DIV2_SHIFT) + 1U) *   \
94      (((CGC_LPAV->PLL4DIV_PFD_0 & CGC_LPAV_PLL4DIV_PFD_0_DIV2HALT_MASK) >> CGC_LPAV_PLL4DIV_PFD_0_DIV2HALT_SHIFT) ^ \
95       1U))
96 #define CGC_LPAV_PLL4DIV_PFD1_DIV1_VAL                                                                              \
97     ((((CGC_LPAV->PLL4DIV_PFD_0 & CGC_LPAV_PLL4DIV_PFD_0_DIV3_MASK) >> CGC_LPAV_PLL4DIV_PFD_0_DIV3_SHIFT) + 1U) *   \
98      (((CGC_LPAV->PLL4DIV_PFD_0 & CGC_LPAV_PLL4DIV_PFD_0_DIV3HALT_MASK) >> CGC_LPAV_PLL4DIV_PFD_0_DIV3HALT_SHIFT) ^ \
99       1U))
100 #define CGC_LPAV_PLL4DIV_PFD1_DIV2_VAL                                                                              \
101     ((((CGC_LPAV->PLL4DIV_PFD_0 & CGC_LPAV_PLL4DIV_PFD_0_DIV4_MASK) >> CGC_LPAV_PLL4DIV_PFD_0_DIV4_SHIFT) + 1U) *   \
102      (((CGC_LPAV->PLL4DIV_PFD_0 & CGC_LPAV_PLL4DIV_PFD_0_DIV4HALT_MASK) >> CGC_LPAV_PLL4DIV_PFD_0_DIV4HALT_SHIFT) ^ \
103       1U))
104 #define CGC_LPAV_PLL4DIV_PFD2_DIV1_VAL                                                                              \
105     ((((CGC_LPAV->PLL4DIV_PFD_1 & CGC_LPAV_PLL4DIV_PFD_1_DIV1_MASK) >> CGC_LPAV_PLL4DIV_PFD_1_DIV1_SHIFT) + 1U) *   \
106      (((CGC_LPAV->PLL4DIV_PFD_1 & CGC_LPAV_PLL4DIV_PFD_1_DIV1HALT_MASK) >> CGC_LPAV_PLL4DIV_PFD_1_DIV1HALT_SHIFT) ^ \
107       1U))
108 #define CGC_LPAV_PLL4DIV_PFD2_DIV2_VAL                                                                              \
109     ((((CGC_LPAV->PLL4DIV_PFD_1 & CGC_LPAV_PLL4DIV_PFD_1_DIV2_MASK) >> CGC_LPAV_PLL4DIV_PFD_1_DIV2_SHIFT) + 1U) *   \
110      (((CGC_LPAV->PLL4DIV_PFD_1 & CGC_LPAV_PLL4DIV_PFD_1_DIV2HALT_MASK) >> CGC_LPAV_PLL4DIV_PFD_1_DIV2HALT_SHIFT) ^ \
111       1U))
112 #define CGC_LPAV_PLL4DIV_PFD3_DIV1_VAL                                                                              \
113     ((((CGC_LPAV->PLL4DIV_PFD_1 & CGC_LPAV_PLL4DIV_PFD_1_DIV3_MASK) >> CGC_LPAV_PLL4DIV_PFD_1_DIV3_SHIFT) + 1U) *   \
114      (((CGC_LPAV->PLL4DIV_PFD_1 & CGC_LPAV_PLL4DIV_PFD_1_DIV3HALT_MASK) >> CGC_LPAV_PLL4DIV_PFD_1_DIV3HALT_SHIFT) ^ \
115       1U))
116 #define CGC_LPAV_PLL4DIV_PFD3_DIV2_VAL                                                                              \
117     ((((CGC_LPAV->PLL4DIV_PFD_1 & CGC_LPAV_PLL4DIV_PFD_1_DIV4_MASK) >> CGC_LPAV_PLL4DIV_PFD_1_DIV4_SHIFT) + 1U) *   \
118      (((CGC_LPAV->PLL4DIV_PFD_1 & CGC_LPAV_PLL4DIV_PFD_1_DIV4HALT_MASK) >> CGC_LPAV_PLL4DIV_PFD_1_DIV4HALT_SHIFT) ^ \
119       1U))
120 
121 #define CGC_PLLPFD_PFD_MAX_VAL (CGC_PLL0PFDCFG_PFD0_MASK >> CGC_PLL0PFDCFG_PFD0_SHIFT)
122 
123 #define CGC_PLL1NUM_NUM_VAL        (uint32_t)((CGC_RTD->PLL1NUM & CGC_PLL1NUM_NUM_MASK) >> CGC_PLL1NUM_NUM_SHIFT)
124 #define CGC_PLL1DENOM_DENOM_VAL    ((CGC_RTD->PLL1DENOM & CGC_PLL1DENOM_DENOM_MASK) >> CGC_PLL1DENOM_DENOM_SHIFT)
125 #define CGC_AD_PLL3NUM_NUM_VAL     (uint32_t)((CGC_AD->PLL3NUM & CGC_AD_PLL3NUM_NUM_MASK) >> CGC_AD_PLL3NUM_NUM_SHIFT)
126 #define CGC_AD_PLL3DENOM_DENOM_VAL ((CGC_AD->PLL3DENOM & CGC_AD_PLL3DENOM_DENOM_MASK) >> CGC_AD_PLL3DENOM_DENOM_SHIFT)
127 #define CGC_LPAV_PLL4NUM_NUM_VAL \
128     (uint32_t)((CGC_LPAV->PLL4NUM & CGC_LPAV_PLL4NUM_NUM_MASK) >> CGC_LPAV_PLL4NUM_NUM_SHIFT)
129 #define CGC_LPAV_PLL4DENOM_DENOM_VAL \
130     ((CGC_LPAV->PLL4DENOM & CGC_LPAV_PLL4DENOM_DENOM_MASK) >> CGC_LPAV_PLL4DENOM_DENOM_SHIFT)
131 
132 #define CGC_PLL0CFG_MULT_VAL      ((CGC_RTD->PLL0CFG & CGC_PLL0CFG_MULT_MASK) >> CGC_PLL0CFG_MULT_SHIFT)
133 #define CGC_PLL1CFG_MULT_VAL      ((CGC_RTD->PLL1CFG & CGC_PLL1CFG_MULT_MASK) >> CGC_PLL1CFG_MULT_SHIFT)
134 #define CGC_AD_PLL3CFG_MULT_VAL   ((CGC_AD->PLL3CFG & CGC_AD_PLL3CFG_MULT_MASK) >> CGC_AD_PLL3CFG_MULT_SHIFT)
135 #define CGC_LPAV_PLL4CFG_MULT_VAL ((CGC_LPAV->PLL4CFG & CGC_LPAV_PLL4CFG_MULT_MASK) >> CGC_LPAV_PLL4CFG_MULT_SHIFT)
136 /*
137  * Constant used to calcul PLL PFD clock frequency
138  * PFD Clock Frequency = PLL output frequency * 18/frac value
139  */
140 #define PFD_FREQ_CALCUL_CONSTANT 18U
141 
142 /*! @brief Get PCC PCS value for enum value defined by clock_ip_src_t. */
143 #define CLOCK_IP_SRC_PCC_PCS(src) (((uint32_t)(src)) & (PCC_CLKCFG_PCS_MASK >> PCC_CLKCFG_PCS_SHIFT))
144 
145 /*******************************************************************************
146  * Variables
147  ******************************************************************************/
148 /* PLL0 multiplier array */
149 static const uint8_t s_pll0Multi[] = {0U, 15U, 16U, 20U, 22U, 25U, 30U, 0U};
150 /* External XTAL (OSC) clock frequency. */
151 volatile uint32_t g_xtal0Freq;
152 /* External XTAL32K clock frequency. */
153 volatile uint32_t g_xtal32Freq;
154 /* External LVDS pad clock frequency. */
155 volatile uint32_t g_lvdsFreq;
156 /* External MCLK pad clock frequency. */
157 volatile uint32_t g_mclkFreq[4];
158 /* RX_BCLK pad clock frequency. */
159 volatile uint32_t g_rxBclkFreq[8];
160 /* TX_BCLK pad clock frequency. */
161 volatile uint32_t g_txBclkFreq[8];
162 /*! Recovered SPDIF_RX clock frequency. */
163 volatile uint32_t g_spdifRxFreq;
164 
165 /*******************************************************************************
166  * Prototypes
167  ******************************************************************************/
168 
169 /*!
170  * @brief Get the common PLL0 frequency for both RAW PLL0 output and PLL0 PFD output.
171  *
172  * The "raw" PLL0 output is the clkout of PLL0.
173  * The "common" PLL0 frequency is the common part for both RAW PLL0 and PLL0 PFD output.
174  * That is the frequency calculated based on the clock source which passes through MULT.
175  * "Common" PLL0 Frequency = Reference Frequency * MULT
176  *
177  * @return  Clock frequency; If the clock is invalid, returns 0.
178  */
179 static uint32_t CLOCK_GetPll0CommonFreq(void);
180 
181 /*!
182  * @brief Get the common PLL1 frequency for both RAW PLL1 output and PLL1 PFD output.
183  *
184  * The "raw" PLL1 output is the clkout of PLL1.
185  * The "common" PLL1 frequency is the common part for both RAW PLL1 and PLL1 PFD output.
186  * That is the frequency calculated based on the clock source which passes through MULT.
187  * "Common" PLL1 Frequency = Reference Frequency * MULT
188  *
189  * @return  Clock frequency; If the clock is invalid, returns 0.
190  */
191 static uint32_t CLOCK_GetPll1CommonFreq(void);
192 
193 /*!
194  * @brief Get the common PLL3 frequency for both RAW PLL3 output and PLL3 PFD output.
195  *
196  * The "raw" PLL3 output is the clkout of PLL3.
197  * The "common" PLL3 frequency is the common part for both RAW PLL3 and PLL3 PFD output.
198  * That is the frequency calculated based on the clock source which passes through MULT.
199  * "Common" PLL3 Frequency = Reference Frequency * MULT
200  *
201  * @return  Clock frequency; If the clock is invalid, returns 0.
202  */
203 static uint32_t CLOCK_GetPll3CommonFreq(void);
204 
205 /*!
206  * @brief Get the common PLL4 frequency for both RAW PLL4 output and PLL4 PFD output.
207  *
208  * The "raw" PLL4 output is the clkout of PLL4.
209  * The "common" PLL4 frequency is the common part for both RAW PLL4 and PLL4 PFD output.
210  * That is the frequency calculated based on the clock source which passes through MULT.
211  * "Common" PLL4 Frequency = Reference Frequency * MULT
212  *
213  * @return  Clock frequency; If the clock is invalid, returns 0.
214  */
215 static uint32_t CLOCK_GetPll4CommonFreq(void);
216 
217 /*******************************************************************************
218  * Code
219  ******************************************************************************/
CLOCK_GetPccInstance(clock_ip_name_t name)220 static uint32_t CLOCK_GetPccInstance(clock_ip_name_t name)
221 {
222     uint32_t i;
223 
224     switch ((uint32_t)name & 0x2FFFF000U)
225     {
226         case (PCC0_BASE & 0x2FFFF000U):
227             i = 0;
228             break;
229         case (PCC1_BASE & 0x2FFFF000U):
230             i = 1;
231             break;
232         case (PCC2_BASE & 0x2FFFF000U):
233             i = 2;
234             break;
235         case (PCC3_BASE & 0x2FFFF000U):
236             i = 3;
237             break;
238         case (PCC4_BASE & 0x2FFFF000U):
239             i = 4;
240             break;
241         case (PCC5_BASE & 0x2FFFF000U):
242             i = 5;
243             break;
244         default:
245             assert(false);
246             i = 0;
247             break;
248     }
249 
250     return i;
251 }
252 
CLOCK_GetMclkFreq(uint32_t index)253 static uint32_t CLOCK_GetMclkFreq(uint32_t index)
254 {
255     assert(g_mclkFreq[index] > 0U); /* Must be set via CLOCK_SetMclkFreq() */
256 
257     return g_mclkFreq[index];
258 }
259 
CLOCK_GetSaiRxBclkFreq(uint32_t instance)260 static uint32_t CLOCK_GetSaiRxBclkFreq(uint32_t instance)
261 {
262     assert(g_rxBclkFreq[instance] > 0U); /* Must be set via CLOCK_SetRxBclkFreq() */
263 
264     return g_rxBclkFreq[instance];
265 }
266 
CLOCK_GetSaiTxBclkFreq(uint32_t instance)267 static uint32_t CLOCK_GetSaiTxBclkFreq(uint32_t instance)
268 {
269     assert(g_txBclkFreq[instance] > 0U); /* Must be set via CLOCK_SetTxBclkFreq() */
270 
271     return g_txBclkFreq[instance];
272 }
273 
CLOCK_GetSpdifRxFreq(void)274 static uint32_t CLOCK_GetSpdifRxFreq(void)
275 {
276     assert(g_spdifRxFreq > 0U); /* Must be set via CLOCK_SetSpdifRxFreq() */
277 
278     return g_spdifRxFreq;
279 }
280 
281 /*!
282  * @brief Set the clock source for specific IP module.
283  *
284  * Set the clock source for specific IP, not all modules need to set the
285  * clock source, should only use this function for the modules need source
286  * setting.
287  *
288  * @param name Which peripheral to check, see \ref clock_ip_name_t.
289  * @param src Clock source to set.
290  */
CLOCK_SetIpSrc(clock_ip_name_t name,clock_ip_src_t src)291 void CLOCK_SetIpSrc(clock_ip_name_t name, clock_ip_src_t src)
292 {
293     uint32_t reg;
294 
295     if (((uint32_t)name & IP_NAME_NON_PCC_FLAG_MASK) == 0UL)
296     {
297         /* PCC register */
298         reg = PCC_REG(name);
299 
300         assert((reg & PCC_CLKCFG_PR_MASK) != 0UL);
301         assert(0UL == (reg & PCC_CLKCFG_INUSE_MASK)); /* Should not change if clock has been enabled by other core. */
302 
303         if (((uint32_t)name & PCC_PCS_AVAIL_MASK) != 0UL)
304         {
305             /* Clear PCS */
306             reg &= ~PCC_CLKCFG_PCS_MASK;
307             switch (name)
308             {
309                 case kCLOCK_Tpm2:
310                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 4U);
311                     if (((uint32_t)src & 0x10U) == 0U)
312                     {
313                         /* Audio clock source */
314                         CGC_RTD->TPM3_2CLK =
315                             (CGC_RTD->TPM3_2CLK & ~CGC_TPM3_2CLK_TPM2CLK_MASK) | CGC_TPM3_2CLK_TPM2CLK(src);
316                     }
317                     else
318                     {
319                         /* PCC Async clock source */
320                         CGC_RTD->TPM3_2CLK =
321                             (CGC_RTD->TPM3_2CLK & ~CGC_TPM3_2CLK_TPM2CLK_MASK) | CGC_TPM3_2CLK_TPM2CLK(2U);
322                         reg |= PCC_CLKCFG_PCS(src);
323                     }
324                     break;
325                 case kCLOCK_Tpm3:
326                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 5U);
327                     if (((uint32_t)src & 0x10U) == 0U)
328                     {
329                         /* Audio clock source */
330                         CGC_RTD->TPM3_2CLK =
331                             (CGC_RTD->TPM3_2CLK & ~CGC_TPM3_2CLK_TPM3CLK_MASK) | CGC_TPM3_2CLK_TPM3CLK(src);
332                     }
333                     else
334                     {
335                         /* PCC Async clock source */
336                         CGC_RTD->TPM3_2CLK =
337                             (CGC_RTD->TPM3_2CLK & ~CGC_TPM3_2CLK_TPM3CLK_MASK) | CGC_TPM3_2CLK_TPM3CLK(3U);
338                         reg |= PCC_CLKCFG_PCS(src);
339                     }
340                     break;
341                 case kCLOCK_Tpm6:
342                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 7U);
343                     if (((uint32_t)src & 0x10U) == 0U)
344                     {
345                         /* Audio clock source */
346                         CGC_AD->TPM6_7CLK =
347                             (CGC_AD->TPM6_7CLK & ~CGC_AD_TPM6_7CLK_TPM6CLK_MASK) | CGC_AD_TPM6_7CLK_TPM6CLK(src);
348                     }
349                     else
350                     {
351                         /* PCC Async clock source */
352                         CGC_AD->TPM6_7CLK =
353                             (CGC_AD->TPM6_7CLK & ~CGC_AD_TPM6_7CLK_TPM6CLK_MASK) | CGC_AD_TPM6_7CLK_TPM6CLK(3U);
354                         reg |= PCC_CLKCFG_PCS(src);
355                     }
356                     break;
357                 case kCLOCK_Tpm7:
358                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 7U);
359                     if (((uint32_t)src & 0x10U) == 0U)
360                     {
361                         /* Audio clock source */
362                         CGC_AD->TPM6_7CLK =
363                             (CGC_AD->TPM6_7CLK & ~CGC_AD_TPM6_7CLK_TPM7CLK_MASK) | CGC_AD_TPM6_7CLK_TPM7CLK(src);
364                     }
365                     else
366                     {
367                         /* PCC Async clock source */
368                         CGC_AD->TPM6_7CLK =
369                             (CGC_AD->TPM6_7CLK & ~CGC_AD_TPM6_7CLK_TPM7CLK_MASK) | CGC_AD_TPM6_7CLK_TPM7CLK(3U);
370                         reg |= PCC_CLKCFG_PCS(src);
371                     }
372                     break;
373                 case kCLOCK_Tpm8:
374                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 9U);
375                     if (((uint32_t)src & 0x10U) == 0U)
376                     {
377                         /* Audio clock source */
378                         CGC_LPAV->TPM8CLK =
379                             (CGC_LPAV->TPM8CLK & ~CGC_LPAV_TPM8CLK_TPM8CLK_MASK) | CGC_LPAV_TPM8CLK_TPM8CLK(src);
380                     }
381                     else
382                     {
383                         /* PCC Async clock source */
384                         CGC_LPAV->TPM8CLK =
385                             (CGC_LPAV->TPM8CLK & ~CGC_LPAV_TPM8CLK_TPM8CLK_MASK) | CGC_LPAV_TPM8CLK_TPM8CLK(5U);
386                         reg |= PCC_CLKCFG_PCS(src);
387                     }
388                     break;
389                 default:
390                     assert((uint32_t)CLOCK_IP_SOURCE_PCC_INDEX_VAL(src) == CLOCK_GetPccInstance(name));
391                     reg |= PCC_CLKCFG_PCS(src);
392                     break;
393             }
394 
395             /*
396              * If clock is already enabled, first disable it, then set the clock
397              * source and re-enable it.
398              */
399             PCC_REG(name) = reg & ~PCC_CLKCFG_CGC_MASK;
400             PCC_REG(name) = reg;
401         }
402         else
403         {
404             switch (name)
405             {
406                 case kCLOCK_Sai0:
407                     /* Audio clock source */
408                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 1U);
409                     CGC_RTD->SAI3_0_CLK =
410                         (CGC_RTD->SAI3_0_CLK & ~CGC_SAI3_0_CLK_SAI0CLK_MASK) | CGC_SAI3_0_CLK_SAI0CLK(src);
411                     break;
412                 case kCLOCK_Sai1:
413                     /* Audio clock source */
414                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 1U);
415                     CGC_RTD->SAI3_0_CLK =
416                         (CGC_RTD->SAI3_0_CLK & ~CGC_SAI3_0_CLK_SAI1CLK_MASK) | CGC_SAI3_0_CLK_SAI1CLK(src);
417                     break;
418                 case kCLOCK_Sai2:
419                     /* Audio clock source */
420                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 2U);
421                     CGC_RTD->SAI3_0_CLK =
422                         (CGC_RTD->SAI3_0_CLK & ~CGC_SAI3_0_CLK_SAI2CLK_MASK) | CGC_SAI3_0_CLK_SAI2CLK(src);
423                     break;
424                 case kCLOCK_Sai3:
425                     /* Audio clock source */
426                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 2U);
427                     CGC_RTD->SAI3_0_CLK =
428                         (CGC_RTD->SAI3_0_CLK & ~CGC_SAI3_0_CLK_SAI3CLK_MASK) | CGC_SAI3_0_CLK_SAI3CLK(src);
429                     break;
430                 case kCLOCK_Sai4:
431                     /* Audio clock source */
432                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 6U);
433                     CGC_AD->SAI5_4_CLK =
434                         (CGC_AD->SAI5_4_CLK & ~CGC_AD_SAI5_4_CLK_SAI4CLK_MASK) | CGC_AD_SAI5_4_CLK_SAI4CLK(src);
435                     break;
436                 case kCLOCK_Sai5:
437                     /* Audio clock source */
438                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 6U);
439                     CGC_AD->SAI5_4_CLK =
440                         (CGC_AD->SAI5_4_CLK & ~CGC_AD_SAI5_4_CLK_SAI5CLK_MASK) | CGC_AD_SAI5_4_CLK_SAI5CLK(src);
441                     break;
442                 case kCLOCK_Sai6:
443                     /* Audio clock source */
444                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 8U);
445                     CGC_LPAV->SAI7_6_CLK =
446                         (CGC_LPAV->SAI7_6_CLK & ~CGC_LPAV_SAI7_6_CLK_SAI6CLK_MASK) | CGC_LPAV_SAI7_6_CLK_SAI6CLK(src);
447                     break;
448                 case kCLOCK_Sai7:
449                     /* Audio clock source */
450                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 8U);
451                     CGC_LPAV->SAI7_6_CLK =
452                         (CGC_LPAV->SAI7_6_CLK & ~CGC_LPAV_SAI7_6_CLK_SAI7CLK_MASK) | CGC_LPAV_SAI7_6_CLK_SAI7CLK(src);
453                     break;
454 
455                 case kCLOCK_Spdif:
456                     /* Audio clock source */
457                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 8U);
458                     CGC_LPAV->SPDIFCLK = CGC_LPAV_SPDIFCLK_SPDIFCLK(src);
459                     break;
460                 case kCLOCK_Micfil:
461                     assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 3U);
462                     CGC_RTD->EMICFIL = CGC_EMICFIL_MICFILCLK(src);
463                     break;
464                 default:
465                     assert(false);
466                     break;
467             }
468         }
469     }
470     else
471     {
472         /* Non-PCC register */
473         if (name == kCLOCK_Mqs0)
474         {
475             assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 1U);
476             CGC_RTD->MQS0CLK = CGC_MQS0CLK_MQS0CLK(src);
477         }
478         else if (name == kCLOCK_Mqs1)
479         {
480             assert(CLOCK_IP_SOURCE_NON_PCC_INDEX_VAL(src) == 6U);
481             CGC_AD->MQS1CLK = CGC_AD_MQS1CLK_MQS1CLK(src);
482         }
483         else
484         {
485             assert(false);
486         }
487     }
488 }
489 
490 /*!
491  * @brief Set the clock source and divider for specific IP module.
492  *
493  * Set the clock source and divider for specific IP, not all modules need to
494  * set the clock source and divider, should only use this function for the
495  * modules need source and divider setting.
496  *
497  * Divider output clock = Divider input clock x [(fracValue+1)/(divValue+1)]).
498  *
499  * @param name Which peripheral to check, see \ref clock_ip_name_t.
500  * @param src Clock source to set.
501  * @param divValue  The divider value.
502  * @param fracValue The fraction multiply value.
503  */
CLOCK_SetIpSrcDiv(clock_ip_name_t name,clock_ip_src_t src,uint8_t divValue,uint8_t fracValue)504 void CLOCK_SetIpSrcDiv(clock_ip_name_t name, clock_ip_src_t src, uint8_t divValue, uint8_t fracValue)
505 {
506     uint32_t reg = PCC_REG(name);
507 
508     assert(((uint32_t)name & IP_NAME_NON_PCC_FLAG_MASK) == 0UL);
509     assert((reg & PCC_CLKCFG_PR_MASK) != 0UL);
510     assert(((uint32_t)name & (PCC_PCS_AVAIL_MASK | PCC_PCD_FRAC_AVAIL_MASK)) ==
511            (PCC_PCS_AVAIL_MASK | PCC_PCD_FRAC_AVAIL_MASK));
512     assert(0UL == (reg & PCC_CLKCFG_INUSE_MASK)); /* Should not change if clock has been enabled by other core. */
513     assert(CLOCK_IP_SOURCE_PCC_INDEX_VAL(src) == CLOCK_GetPccInstance(name));
514 
515     reg = (reg & ~(PCC_CLKCFG_PCS_MASK | PCC_CLKCFG_FRAC_MASK | PCC_CLKCFG_PCD_MASK)) | PCC_CLKCFG_PCS(src) |
516           PCC_CLKCFG_PCD(divValue) | PCC_CLKCFG_FRAC(fracValue);
517 
518     /*
519      * If clock is already enabled, first disable it, then set the clock
520      * source and re-enable it.
521      */
522     PCC_REG(name) = reg & ~PCC_CLKCFG_CGC_MASK;
523     PCC_REG(name) = reg;
524 }
525 
526 /*!
527  * brief Get the external LVDS pad clock frequency (LVDS).
528  *
529  * return Clock frequency in Hz.
530  */
CLOCK_GetLvdsClkFreq(void)531 uint32_t CLOCK_GetLvdsClkFreq(void)
532 {
533     assert(g_lvdsFreq);
534     return g_lvdsFreq;
535 }
536 
537 /*!
538  * brief Get the CM33 slow clock frequency.
539  *
540  * return Clock frequency in Hz.
541  */
CLOCK_GetCm33SlowClkFreq(void)542 uint32_t CLOCK_GetCm33SlowClkFreq(void)
543 {
544     return CLOCK_GetCm33SysClkFreq(kCGC_SysClkSlow);
545 }
546 
547 /*!
548  * brief Get the CM33 bus clock frequency.
549  *
550  * return Clock frequency in Hz.
551  */
CLOCK_GetCm33BusClkFreq(void)552 uint32_t CLOCK_GetCm33BusClkFreq(void)
553 {
554     return CLOCK_GetCm33SysClkFreq(kCGC_SysClkBus);
555 }
556 
557 /*!
558  * brief Get the CM33 core/platform clock frequency.
559  *
560  * return Clock frequency in Hz.
561  */
CLOCK_GetCm33CorePlatClkFreq(void)562 uint32_t CLOCK_GetCm33CorePlatClkFreq(void)
563 {
564     return CLOCK_GetCm33SysClkFreq(kCGC_SysClkCorePlat);
565 }
566 
567 /*!
568  * brief Get the Fusion DSP slow clock frequency.
569  *
570  * return Clock frequency in Hz.
571  */
CLOCK_GetFusionDspSlowClkFreq(void)572 uint32_t CLOCK_GetFusionDspSlowClkFreq(void)
573 {
574     return CLOCK_GetFusionDspSysClkFreq(kCGC_SysClkSlow);
575 }
576 
577 /*!
578  * brief Get the Fusion DSP bus clock frequency.
579  *
580  * return Clock frequency in Hz.
581  */
CLOCK_GetFusionDspBusClkFreq(void)582 uint32_t CLOCK_GetFusionDspBusClkFreq(void)
583 {
584     return CLOCK_GetFusionDspSysClkFreq(kCGC_SysClkBus);
585 }
586 
587 /*!
588  * brief Get the Fusion DSP core/platform clock frequency.
589  *
590  * return Clock frequency in Hz.
591  */
CLOCK_GetFusionDspCorePlatClkFreq(void)592 uint32_t CLOCK_GetFusionDspCorePlatClkFreq(void)
593 {
594     return CLOCK_GetFusionDspSysClkFreq(kCGC_SysClkCorePlat);
595 }
596 
597 /*!
598  * @brief Gets the CGC XBAR bus clock frequency in AD.
599  *
600  * This function gets the CGC XBAR bus clock frequency.
601  *
602  * @return  Clock frequency.
603  */
CLOCK_GetXbarBusClkFreq(void)604 uint32_t CLOCK_GetXbarBusClkFreq(void)
605 {
606     uint32_t freq;
607     uint32_t nicClk      = CGC_AD->NICCLK;
608     uint32_t xbarClk     = CGC_AD->XBARCLK;
609     uint32_t scs         = (nicClk & CGC_AD_NICCLK_SCS_MASK) >> CGC_AD_NICCLK_SCS_SHIFT;
610     uint32_t divNicPlat  = (nicClk & CGC_AD_NICCLK_NIC_AD_DIVPLAT_MASK) >> CGC_AD_NICCLK_NIC_AD_DIVPLAT_SHIFT;
611     uint32_t divXbarPlat = (xbarClk & CGC_AD_XBARCLK_XBAR_AD_DIVPLAT_MASK) >> CGC_AD_XBARCLK_XBAR_AD_DIVPLAT_SHIFT;
612     uint32_t divXbarBus  = (xbarClk & CGC_AD_XBARCLK_XBAR_DIVBUS_MASK) >> CGC_AD_XBARCLK_XBAR_DIVBUS_SHIFT;
613 
614     switch (scs)
615     {
616         case (uint32_t)kCGC_NicSysClkSrcFro:
617             freq = CLOCK_GetFroFreq();
618             break;
619         case (uint32_t)kCGC_NicSysClkSrcPll3Pfd0:
620             freq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd0Clk);
621             break;
622         case (uint32_t)kCGC_NicSysClkSrcSysOsc:
623             freq = CLOCK_GetSysOscFreq();
624             break;
625         case (uint32_t)kCGC_NicSysClkSrcLvds:
626             freq = CLOCK_GetLvdsClkFreq();
627             break;
628         default:
629             freq = 0U;
630             break;
631     }
632 
633     freq /= (divNicPlat + 1U) * (divXbarPlat + 1U) * (divXbarBus + 1U);
634 
635     return freq;
636 }
637 
638 /*!
639  * @brief Gets the CGC HIFI DSP system clock frequency in LPAV.
640  *
641  * This function gets the CGC HIFI DSP system clock frequency. These clocks are used for
642  * core, platform domains.
643  *
644  * @param type     Which type of clock to get.
645  * @return  Clock frequency.
646  */
CLOCK_GetHifiDspSysClkFreq(cgc_sys_clk_t type)647 uint32_t CLOCK_GetHifiDspSysClkFreq(cgc_sys_clk_t type)
648 {
649     uint32_t freq;
650     uint32_t sysClkConfig              = 0U;
651     cgc_hifi_sys_clk_config_t *pConfig = NULL;
652 
653     (void)memcpy((void *)&sysClkConfig, (void *)&CGC_LPAV->HIFICLK, sizeof(sysClkConfig));
654     pConfig = (cgc_hifi_sys_clk_config_t *)(uint32_t)&sysClkConfig;
655     switch (pConfig->src)
656     {
657         case (uint32_t)kCGC_HifiSysClkSrcFro:
658             freq = CLOCK_GetFroFreq();
659             break;
660         case (uint32_t)kCGC_HifiSysClkSrcPll4:
661             freq = CLOCK_GetPll4Freq();
662             break;
663         case (uint32_t)kCGC_HifiSysClkSrcPll4Pfd0:
664             freq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd0Clk);
665             break;
666         case (uint32_t)kCGC_HifiSysClkSrcSysOsc:
667             freq = CLOCK_GetSysOscFreq();
668             break;
669         case (uint32_t)kCGC_HifiSysClkSrcLvds:
670             freq = CLOCK_GetLvdsClkFreq();
671             break;
672         default:
673             freq = 0U;
674             break;
675     }
676 
677     freq /= (pConfig->divCore + 1U);
678 
679     if (kCGC_SysClkNicHifi == type)
680     {
681         freq /= (pConfig->divPlat + 1U);
682     }
683     else
684     {
685         assert(kCGC_SysClkHifi4 == type);
686     }
687 
688     return freq;
689 }
690 
691 /*!
692  * @brief Gets the CGC NIC LPAV system clock frequency in LPAV.
693  *
694  * This function gets the CGC NIC LPAV system clock frequency. These clocks are used for
695  * AXI, AHB, Bus domains.
696  *
697  * @param type     Which type of clock to get.
698  * @return  Clock frequency.
699  */
CLOCK_GetLpavSysClkFreq(cgc_sys_clk_t type)700 uint32_t CLOCK_GetLpavSysClkFreq(cgc_sys_clk_t type)
701 {
702     uint32_t freq;
703     uint32_t sysClkConfig              = 0U;
704     cgc_lpav_sys_clk_config_t *pConfig = NULL;
705 
706     (void)memcpy((void *)&sysClkConfig, (void *)&CGC_LPAV->NICLPAVCLK, sizeof(sysClkConfig));
707     pConfig = (cgc_lpav_sys_clk_config_t *)(uint32_t)&sysClkConfig;
708 
709     switch (pConfig->src)
710     {
711         case (uint32_t)kCGC_LpavSysClkSrcFro:
712             freq = CLOCK_GetFroFreq();
713             break;
714         case (uint32_t)kCGC_LpavSysClkSrcPll4Pfd1:
715             freq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd1Clk);
716             break;
717         case (uint32_t)kCGC_LpavSysClkSrcSysOsc:
718             freq = CLOCK_GetSysOscFreq();
719             break;
720         case (uint32_t)kCGC_LpavSysClkSrcLvds:
721             freq = CLOCK_GetLvdsClkFreq();
722             break;
723         default:
724             freq = 0U;
725             break;
726     }
727 
728     freq /= (pConfig->divAxi + 1U);
729 
730     if (kCGC_SysClkLpavAhb == type)
731     {
732         freq /= (pConfig->divAhb + 1U);
733     }
734     else if (kCGC_SysClkLpavBus == type)
735     {
736         freq /= (pConfig->divBus + 1U);
737     }
738     else
739     {
740         assert(kCGC_SysClkLpavAxi == type);
741     }
742 
743     return freq;
744 }
745 
746 /*!
747  * @brief Gets the CGC DDR clock frequency in LPAV.
748  *
749  * This function gets the CGC DDR clock frequency.
750  *
751  * @return  Clock frequency.
752  */
CLOCK_GetDdrClkFreq(void)753 uint32_t CLOCK_GetDdrClkFreq(void)
754 {
755     uint32_t freq;
756     uint32_t sysClkConfig             = 0U;
757     cgc_ddr_sys_clk_config_t *pConfig = NULL;
758 
759     (void)memcpy((void *)&sysClkConfig, (void *)&CGC_LPAV->DDRCLK, sizeof(sysClkConfig));
760     pConfig = (cgc_ddr_sys_clk_config_t *)(uint32_t)&sysClkConfig;
761 
762     /* TODO: 2 cascaded switches */
763     switch (pConfig->src)
764     {
765         case (uint32_t)kCGC_DdrSysClkSrcFro:
766             freq = CLOCK_GetFroFreq();
767             break;
768         case (uint32_t)kCGC_DdrSysClkSrcPll4Pfd1:
769             freq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd1Clk);
770             break;
771         case (uint32_t)kCGC_DdrSysClkSrcSysOsc:
772             freq = CLOCK_GetSysOscFreq();
773             break;
774         case (uint32_t)kCGC_DdrSysClkSrcLvds:
775             freq = CLOCK_GetLvdsClkFreq();
776             break;
777         default:
778             freq = 0U;
779             break;
780     }
781 
782     freq /= (pConfig->divDdr + 1U);
783 
784     return freq;
785 }
786 
787 /*!
788  * brief Gets the clock frequency for a specific clock name.
789  *
790  * This function checks the current clock configurations and then calculates
791  * the clock frequency for a specific clock name defined in clock_name_t.
792  *
793  * param clockName Clock names defined in clock_name_t
794  * return Clock frequency value in hertz
795  */
CLOCK_GetFreq(clock_name_t clockName)796 uint32_t CLOCK_GetFreq(clock_name_t clockName)
797 {
798     uint32_t freq;
799 
800     switch (clockName)
801     {
802         case kCLOCK_Cm33CorePlatClk:
803             freq = CLOCK_GetCm33SysClkFreq(kCGC_SysClkCorePlat);
804             break;
805         case kCLOCK_Cm33BusClk:
806             freq = CLOCK_GetCm33SysClkFreq(kCGC_SysClkBus);
807             break;
808         case kCLOCK_Cm33SlowClk:
809             freq = CLOCK_GetCm33SysClkFreq(kCGC_SysClkSlow);
810             break;
811         case kCLOCK_FusionDspCorePlatClk:
812             freq = CLOCK_GetFusionDspSysClkFreq(kCGC_SysClkCorePlat);
813             break;
814         case kCLOCK_FusionDspBusClk:
815             freq = CLOCK_GetFusionDspSysClkFreq(kCGC_SysClkBus);
816             break;
817         case kCLOCK_FusionDspSlowClk:
818             freq = CLOCK_GetFusionDspSysClkFreq(kCGC_SysClkSlow);
819             break;
820 
821         case kCLOCK_XbarBusClk:
822             freq = CLOCK_GetXbarBusClkFreq();
823             break;
824 
825         case kCLOCK_HifiDspClk:
826             freq = CLOCK_GetHifiDspSysClkFreq(kCGC_SysClkHifi4);
827             break;
828         case kCLOCK_HifiNicPlatClk:
829             freq = CLOCK_GetHifiDspSysClkFreq(kCGC_SysClkNicHifi);
830             break;
831         case kCLOCK_NicLpavAxiClk:
832             freq = CLOCK_GetLpavSysClkFreq(kCGC_SysClkLpavAxi);
833             break;
834         case kCLOCK_NicLpavAhbClk:
835             freq = CLOCK_GetLpavSysClkFreq(kCGC_SysClkLpavAhb);
836             break;
837         case kCLOCK_NicLpavBusClk:
838             freq = CLOCK_GetLpavSysClkFreq(kCGC_SysClkLpavBus);
839             break;
840         case kCLOCK_DdrClk:
841             freq = CLOCK_GetDdrClkFreq();
842             break;
843 
844         case kCLOCK_SysOscClk:
845             freq = CLOCK_GetSysOscFreq();
846             break;
847         case kCLOCK_FroClk:
848             freq = CLOCK_GetFroFreq();
849             break;
850         case kCLOCK_LpOscClk:
851             freq = CLOCK_GetLpOscFreq();
852             break;
853         case kCLOCK_RtcOscClk:
854             freq = CLOCK_GetRtcOscFreq();
855             break;
856         case kCLOCK_LvdsClk:
857             freq = CLOCK_GetLvdsClkFreq();
858             break;
859 
860         case kCLOCK_RtdSysOscDiv1Clk:
861             freq = CLOCK_GetRtdSysOscAsyncFreq(kCGC_AsyncDiv1Clk);
862             break;
863         case kCLOCK_RtdSysOscDiv2Clk:
864             freq = CLOCK_GetRtdSysOscAsyncFreq(kCGC_AsyncDiv2Clk);
865             break;
866         case kCLOCK_RtdSysOscDiv3Clk:
867             freq = CLOCK_GetRtdSysOscAsyncFreq(kCGC_AsyncDiv3Clk);
868             break;
869 
870         case kCLOCK_RtdFroDiv1Clk:
871             freq = CLOCK_GetRtdFroAsyncFreq(kCGC_AsyncDiv1Clk);
872             break;
873         case kCLOCK_RtdFroDiv2Clk:
874             freq = CLOCK_GetRtdFroAsyncFreq(kCGC_AsyncDiv2Clk);
875             break;
876         case kCLOCK_RtdFroDiv3Clk:
877             freq = CLOCK_GetRtdFroAsyncFreq(kCGC_AsyncDiv3Clk);
878             break;
879 
880         case kCLOCK_AdSysOscDiv1Clk:
881             freq = CLOCK_GetAdSysOscAsyncFreq(kCGC_AsyncDiv1Clk);
882             break;
883         case kCLOCK_AdSysOscDiv2Clk:
884             freq = CLOCK_GetAdSysOscAsyncFreq(kCGC_AsyncDiv2Clk);
885             break;
886         case kCLOCK_AdSysOscDiv3Clk:
887             freq = CLOCK_GetAdSysOscAsyncFreq(kCGC_AsyncDiv3Clk);
888             break;
889 
890         case kCLOCK_AdFroDiv1Clk:
891             freq = CLOCK_GetAdFroAsyncFreq(kCGC_AsyncDiv1Clk);
892             break;
893         case kCLOCK_AdFroDiv2Clk:
894             freq = CLOCK_GetAdFroAsyncFreq(kCGC_AsyncDiv2Clk);
895             break;
896         case kCLOCK_AdFroDiv3Clk:
897             freq = CLOCK_GetAdFroAsyncFreq(kCGC_AsyncDiv3Clk);
898             break;
899 
900         case kCLOCK_LpavSysOscDiv1Clk:
901             freq = CLOCK_GetLpavSysOscAsyncFreq(kCGC_AsyncDiv1Clk);
902             break;
903         case kCLOCK_LpavSysOscDiv2Clk:
904             freq = CLOCK_GetLpavSysOscAsyncFreq(kCGC_AsyncDiv2Clk);
905             break;
906         case kCLOCK_LpavSysOscDiv3Clk:
907             freq = CLOCK_GetLpavSysOscAsyncFreq(kCGC_AsyncDiv3Clk);
908             break;
909 
910         case kCLOCK_LpavFroDiv1Clk:
911             freq = CLOCK_GetLpavFroAsyncFreq(kCGC_AsyncDiv1Clk);
912             break;
913         case kCLOCK_LpavFroDiv2Clk:
914             freq = CLOCK_GetLpavFroAsyncFreq(kCGC_AsyncDiv2Clk);
915             break;
916         case kCLOCK_LpavFroDiv3Clk:
917             freq = CLOCK_GetLpavFroAsyncFreq(kCGC_AsyncDiv3Clk);
918             break;
919 
920         case kCLOCK_Pll0Clk:
921             freq = CLOCK_GetPll0Freq();
922             break;
923         case kCLOCK_Pll1Clk:
924             freq = CLOCK_GetPll1Freq();
925             break;
926         case kCLOCK_Pll3Clk:
927             freq = CLOCK_GetPll3Freq();
928             break;
929         case kCLOCK_Pll4Clk:
930             freq = CLOCK_GetPll4Freq();
931             break;
932 
933         case kCLOCK_Pll0Pfd0Clk:
934             freq = CLOCK_GetPll0PfdFreq(kCGC_PllPfd0Clk);
935             break;
936         case kCLOCK_Pll0Pfd1Clk:
937             freq = CLOCK_GetPll0PfdFreq(kCGC_PllPfd1Clk);
938             break;
939         case kCLOCK_Pll0Pfd2Clk:
940             freq = CLOCK_GetPll0PfdFreq(kCGC_PllPfd2Clk);
941             break;
942         case kCLOCK_Pll0Pfd3Clk:
943             freq = CLOCK_GetPll0PfdFreq(kCGC_PllPfd3Clk);
944             break;
945 
946         case kCLOCK_Pll1Pfd0Clk:
947             freq = CLOCK_GetPll1PfdFreq(kCGC_PllPfd0Clk);
948             break;
949         case kCLOCK_Pll1Pfd1Clk:
950             freq = CLOCK_GetPll1PfdFreq(kCGC_PllPfd1Clk);
951             break;
952         case kCLOCK_Pll1Pfd2Clk:
953             freq = CLOCK_GetPll1PfdFreq(kCGC_PllPfd2Clk);
954             break;
955         case kCLOCK_Pll1Pfd3Clk:
956             freq = CLOCK_GetPll1PfdFreq(kCGC_PllPfd3Clk);
957             break;
958 
959         case kCLOCK_Pll3Pfd0Clk:
960             freq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd0Clk);
961             break;
962         case kCLOCK_Pll3Pfd1Clk:
963             freq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd1Clk);
964             break;
965         case kCLOCK_Pll3Pfd2Clk:
966             freq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd2Clk);
967             break;
968         case kCLOCK_Pll3Pfd3Clk:
969             freq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd3Clk);
970             break;
971 
972         case kCLOCK_Pll4Pfd0Clk:
973             freq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd0Clk);
974             break;
975         case kCLOCK_Pll4Pfd1Clk:
976             freq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd1Clk);
977             break;
978         case kCLOCK_Pll4Pfd2Clk:
979             freq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd2Clk);
980             break;
981         case kCLOCK_Pll4Pfd3Clk:
982             freq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd3Clk);
983             break;
984 
985         case kCLOCK_Pll0VcoDivClk:
986             freq = CLOCK_GetPll0AsyncFreq(kCGC_AsyncVcoClk);
987             break;
988         case kCLOCK_Pll0Pfd1DivClk:
989             freq = CLOCK_GetPll0AsyncFreq(kCGC_AsyncPfd1Div1Clk);
990             break;
991         case kCLOCK_Pll0Pfd2DivClk:
992             freq = CLOCK_GetPll0AsyncFreq(kCGC_AsyncPfd2Div1Clk);
993             break;
994 
995         case kCLOCK_Pll1VcoDivClk:
996             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncVcoClk);
997             break;
998         case kCLOCK_Pll1Pfd1DivClk:
999             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd1Div1Clk);
1000             break;
1001         case kCLOCK_Pll1Pfd2DivClk:
1002             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd2Div1Clk);
1003             break;
1004 
1005         case kCLOCK_Pll3VcoDivClk:
1006             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncVcoClk);
1007             break;
1008         case kCLOCK_Pll3Pfd0Div1Clk:
1009             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd0Div1Clk);
1010             break;
1011         case kCLOCK_Pll3Pfd0Div2Clk:
1012             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd0Div2Clk);
1013             break;
1014         case kCLOCK_Pll3Pfd1Div1Clk:
1015             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd1Div1Clk);
1016             break;
1017         case kCLOCK_Pll3Pfd1Div2Clk:
1018             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd1Div2Clk);
1019             break;
1020         case kCLOCK_Pll3Pfd2Div1Clk:
1021             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd2Div1Clk);
1022             break;
1023         case kCLOCK_Pll3Pfd2Div2Clk:
1024             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd2Div2Clk);
1025             break;
1026         case kCLOCK_Pll3Pfd3Div1Clk:
1027             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd3Div1Clk);
1028             break;
1029         case kCLOCK_Pll3Pfd3Div2Clk:
1030             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd3Div2Clk);
1031             break;
1032 
1033         case kCLOCK_Pll4VcoDivClk:
1034             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncVcoClk);
1035             break;
1036         case kCLOCK_Pll4Pfd0Div1Clk:
1037             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd0Div1Clk);
1038             break;
1039         case kCLOCK_Pll4Pfd0Div2Clk:
1040             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd0Div2Clk);
1041             break;
1042         case kCLOCK_Pll4Pfd1Div1Clk:
1043             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd1Div1Clk);
1044             break;
1045         case kCLOCK_Pll4Pfd1Div2Clk:
1046             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd1Div2Clk);
1047             break;
1048         case kCLOCK_Pll4Pfd2Div1Clk:
1049             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd2Div1Clk);
1050             break;
1051         case kCLOCK_Pll4Pfd2Div2Clk:
1052             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd2Div2Clk);
1053             break;
1054         case kCLOCK_Pll4Pfd3Div1Clk:
1055             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd3Div1Clk);
1056             break;
1057         case kCLOCK_Pll4Pfd3Div2Clk:
1058             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd3Div2Clk);
1059             break;
1060         default:
1061             freq = 0U;
1062             break;
1063     }
1064     return freq;
1065 }
1066 
CLOCK_GetPcc0PlatFreq(uint32_t pcs)1067 static uint32_t CLOCK_GetPcc0PlatFreq(uint32_t pcs)
1068 {
1069     uint32_t freq;
1070 
1071     switch (pcs)
1072     {
1073         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0PlatIpSrcSysOscDiv1):
1074             freq = CLOCK_GetRtdSysOscAsyncFreq(kCGC_AsyncDiv1Clk);
1075             break;
1076         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0PlatIpSrcFroDiv1):
1077             freq = CLOCK_GetRtdFroAsyncFreq(kCGC_AsyncDiv1Clk);
1078             break;
1079         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0PlatIpSrcCm33Plat):
1080             freq = CLOCK_GetCm33CorePlatClkFreq();
1081             break;
1082         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0PlatIpSrcFro):
1083             freq = CLOCK_GetFroFreq();
1084             break;
1085         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0PlatIpSrcPll0Pfd3):
1086             freq = CLOCK_GetPll0PfdFreq(kCGC_PllPfd3Clk);
1087             break;
1088         default:
1089             freq = 0U;
1090             break;
1091     }
1092 
1093     return freq;
1094 }
1095 
CLOCK_GetPcc0BusFreq(uint32_t pcs)1096 static uint32_t CLOCK_GetPcc0BusFreq(uint32_t pcs)
1097 {
1098     uint32_t freq;
1099 
1100     switch (pcs)
1101     {
1102         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0BusIpSrcLpo):
1103             freq = CLOCK_GetLpOscFreq();
1104             break;
1105         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0BusIpSrcSysOscDiv2):
1106             freq = CLOCK_GetRtdSysOscAsyncFreq(kCGC_AsyncDiv2Clk);
1107             break;
1108         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0BusIpSrcFroDiv2):
1109             freq = CLOCK_GetRtdFroAsyncFreq(kCGC_AsyncDiv2Clk);
1110             break;
1111         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0BusIpSrcCm33Bus):
1112             freq = CLOCK_GetCm33BusClkFreq();
1113             break;
1114         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0BusIpSrcPll1Pfd1Div):
1115             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd1Div1Clk);
1116             break;
1117         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0BusIpSrcPll0Pfd2Div):
1118             freq = CLOCK_GetPll0AsyncFreq(kCGC_AsyncPfd2Div1Clk);
1119             break;
1120         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc0BusIpSrcPll0Pfd1Div):
1121             freq = CLOCK_GetPll0AsyncFreq(kCGC_AsyncPfd1Div1Clk);
1122             break;
1123         default:
1124             freq = 0U;
1125             break;
1126     }
1127 
1128     return freq;
1129 }
1130 
CLOCK_GetPcc1PlatFreq(uint32_t pcs)1131 static uint32_t CLOCK_GetPcc1PlatFreq(uint32_t pcs)
1132 {
1133     return CLOCK_GetPcc0PlatFreq(pcs);
1134 }
1135 
CLOCK_GetPcc1BusFreq(uint32_t pcs)1136 static uint32_t CLOCK_GetPcc1BusFreq(uint32_t pcs)
1137 {
1138     uint32_t freq;
1139 
1140     if (pcs == (uint32_t)kCLOCK_Pcc1BusIpSrcPll1VcoDiv)
1141     {
1142         freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncVcoClk);
1143     }
1144     else
1145     {
1146         freq = CLOCK_GetPcc0BusFreq(pcs);
1147     }
1148 
1149     return freq;
1150 }
1151 
CLOCK_GetPcc2BusFreq(uint32_t pcs)1152 static uint32_t CLOCK_GetPcc2BusFreq(uint32_t pcs)
1153 {
1154     uint32_t freq;
1155 
1156     switch (pcs)
1157     {
1158         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc2BusIpSrcLpo):
1159             freq = CLOCK_GetLpOscFreq();
1160             break;
1161         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc2BusIpSrcSysOscDiv3):
1162             freq = CLOCK_GetRtdSysOscAsyncFreq(kCGC_AsyncDiv3Clk);
1163             break;
1164         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc2BusIpSrcFroDiv3):
1165             freq = CLOCK_GetRtdFroAsyncFreq(kCGC_AsyncDiv3Clk);
1166             break;
1167         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc2BusIpSrcFusionDspBus):
1168             freq = CLOCK_GetFusionDspBusClkFreq();
1169             break;
1170         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc2BusIpSrcPll1VcoDiv):
1171             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncVcoClk);
1172             break;
1173         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc2BusIpSrcPll0Pfd2Div):
1174             freq = CLOCK_GetPll0AsyncFreq(kCGC_AsyncPfd2Div1Clk);
1175             break;
1176         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc2BusIpSrcPll0Pfd1Div):
1177             freq = CLOCK_GetPll0AsyncFreq(kCGC_AsyncPfd1Div1Clk);
1178             break;
1179         default:
1180             freq = 0U;
1181             break;
1182     }
1183 
1184     return freq;
1185 }
1186 
CLOCK_GetPcc3BusFreq(uint32_t pcs)1187 static uint32_t CLOCK_GetPcc3BusFreq(uint32_t pcs)
1188 {
1189     uint32_t freq;
1190 
1191     switch (pcs)
1192     {
1193         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc3BusIpSrcLpo):
1194             freq = CLOCK_GetLpOscFreq();
1195             break;
1196         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc3BusIpSrcSysOscDiv2):
1197             freq = CLOCK_GetAdSysOscAsyncFreq(kCGC_AsyncDiv2Clk);
1198             break;
1199         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc3BusIpSrcFroDiv2):
1200             freq = CLOCK_GetAdFroAsyncFreq(kCGC_AsyncDiv2Clk);
1201             break;
1202         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc3BusIpSrcXbarBus):
1203             freq = CLOCK_GetXbarBusClkFreq();
1204             break;
1205         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc3BusIpSrcPll3Pfd1Div1):
1206             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd1Div1Clk);
1207             break;
1208         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc3BusIpSrcPll3Pfd0Div2):
1209             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd0Div2Clk);
1210             break;
1211         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc3BusIpSrcPll3Pfd0Div1):
1212             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd0Div1Clk);
1213             break;
1214         default:
1215             freq = 0U;
1216             break;
1217     }
1218 
1219     return freq;
1220 }
1221 
CLOCK_GetPcc4PlatFreq(uint32_t pcs)1222 static uint32_t CLOCK_GetPcc4PlatFreq(uint32_t pcs)
1223 {
1224     uint32_t freq;
1225 
1226     switch (pcs)
1227     {
1228         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4PlatIpSrcSysOscDiv1):
1229             freq = CLOCK_GetAdSysOscAsyncFreq(kCGC_AsyncDiv1Clk);
1230             break;
1231         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4PlatIpSrcFroDiv1):
1232             freq = CLOCK_GetAdFroAsyncFreq(kCGC_AsyncDiv1Clk);
1233             break;
1234         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4PlatIpSrcPll3Pfd3Div2):
1235             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd3Div2Clk);
1236             break;
1237         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4PlatIpSrcPll3Pfd3Div1):
1238             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd3Div1Clk);
1239             break;
1240         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4PlatIpSrcPll3Pfd2Div2):
1241             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd2Div2Clk);
1242             break;
1243         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4PlatIpSrcPll3Pfd2Div1):
1244             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd2Div1Clk);
1245             break;
1246         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4PlatIpSrcPll3Pfd1Div2):
1247             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd1Div2Clk);
1248             break;
1249         default:
1250             freq = 0U;
1251             break;
1252     }
1253 
1254     return freq;
1255 }
1256 
CLOCK_GetPcc4BusFreq(uint32_t pcs)1257 static uint32_t CLOCK_GetPcc4BusFreq(uint32_t pcs)
1258 {
1259     uint32_t freq;
1260 
1261     switch (pcs)
1262     {
1263         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4BusIpSrcLpo):
1264             freq = CLOCK_GetLpOscFreq();
1265             break;
1266         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4BusIpSrcSysOscDiv2):
1267             freq = CLOCK_GetAdSysOscAsyncFreq(kCGC_AsyncDiv2Clk);
1268             break;
1269         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4BusIpSrcFroDiv2):
1270             freq = CLOCK_GetAdFroAsyncFreq(kCGC_AsyncDiv2Clk);
1271             break;
1272         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4BusIpSrcXbarBus):
1273             freq = CLOCK_GetXbarBusClkFreq();
1274             break;
1275         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4BusIpSrcPll3VcoDiv):
1276             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncVcoClk);
1277             break;
1278         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc4BusIpSrcPll3Pfd0Div1):
1279             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd0Div1Clk);
1280             break;
1281         default:
1282             freq = 0U;
1283             break;
1284     }
1285 
1286     return freq;
1287 }
1288 
CLOCK_GetPcc5PlatFreq(uint32_t pcs)1289 static uint32_t CLOCK_GetPcc5PlatFreq(uint32_t pcs)
1290 {
1291     uint32_t freq;
1292 
1293     switch (pcs)
1294     {
1295         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5PlatIpSrcPll4Pfd3Div2):
1296             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd3Div2Clk);
1297             break;
1298         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5PlatIpSrcPll4Pfd2Div2):
1299             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd2Div2Clk);
1300             break;
1301         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5PlatIpSrcPll4Pfd2Div1):
1302             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd2Div1Clk);
1303             break;
1304         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5PlatIpSrcPll4Pfd1Div2):
1305             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd1Div2Clk);
1306             break;
1307         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5PlatIpSrcPll4Pfd1Div1):
1308             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd1Div1Clk);
1309             break;
1310         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5PlatIpSrcPll4Pfd0Div2):
1311             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd0Div2Clk);
1312             break;
1313         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5PlatIpSrcPll4Pfd0Div1):
1314             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd0Div1Clk);
1315             break;
1316         default:
1317             freq = 0U;
1318             break;
1319     }
1320 
1321     return freq;
1322 }
1323 
CLOCK_GetPcc5BusFreq(uint32_t pcs)1324 static uint32_t CLOCK_GetPcc5BusFreq(uint32_t pcs)
1325 {
1326     uint32_t freq;
1327 
1328     switch (pcs)
1329     {
1330         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5BusIpSrcLpo):
1331             freq = CLOCK_GetLpOscFreq();
1332             break;
1333         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5BusIpSrcSysOscDiv2):
1334             freq = CLOCK_GetLpavSysOscAsyncFreq(kCGC_AsyncDiv2Clk);
1335             break;
1336         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5BusIpSrcFroDiv2):
1337             freq = CLOCK_GetLpavFroAsyncFreq(kCGC_AsyncDiv2Clk);
1338             break;
1339         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5BusIpSrcLpavBus):
1340             freq = CLOCK_GetLpavSysClkFreq(kCGC_SysClkLpavBus);
1341             break;
1342         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5BusIpSrcPll4VcoDiv):
1343             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncVcoClk);
1344             break;
1345         case CLOCK_IP_SRC_PCC_PCS(kCLOCK_Pcc5BusIpSrcPll4Pfd3Div1):
1346             freq = CLOCK_GetPll4AsyncFreq(kCGC_AsyncPfd3Div1Clk);
1347             break;
1348         default:
1349             freq = 0U;
1350             break;
1351     }
1352 
1353     return freq;
1354 }
1355 
CLOCK_GetPccFreq(uint32_t pccInst,clock_ip_name_t name,uint32_t reg)1356 static uint32_t CLOCK_GetPccFreq(uint32_t pccInst, clock_ip_name_t name, uint32_t reg)
1357 {
1358     uint32_t freq = 0U;
1359 
1360     switch (pccInst)
1361     {
1362         case 0:
1363         case 1:
1364             switch (name)
1365             {
1366                 case kCLOCK_Wdog0:
1367                 case kCLOCK_Wdog1:
1368                 case kCLOCK_Lpit0:
1369                 case kCLOCK_Flexio0:
1370                 case kCLOCK_I3c0:
1371                 case kCLOCK_Lpspi0:
1372                 case kCLOCK_Lpspi1:
1373                 case kCLOCK_Adc0:
1374                 case kCLOCK_Adc1:
1375                 case kCLOCK_Dac0:
1376                 case kCLOCK_Dac1:
1377                 case kCLOCK_SentinelLpuart:
1378                 case kCLOCK_PowersysWdog:
1379                 case kCLOCK_Tpm0:
1380                 case kCLOCK_Tpm1:
1381                 case kCLOCK_Lpi2c0:
1382                 case kCLOCK_Lpi2c1:
1383                 case kCLOCK_Lpuart0:
1384                 case kCLOCK_Lpuart1:
1385                 case kCLOCK_Flexcan:
1386                     freq = (pccInst == 0U) ? CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg)) :
1387                                              CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg));
1388                     break;
1389                 case kCLOCK_Flexspi0:
1390                 case kCLOCK_Flexspi1:
1391                 case kCLOCK_Tpiu:
1392                 case kCLOCK_Swo:
1393                     /* PCC0/PCC1 has same platform PCC selection. */
1394                     freq = CLOCK_GetPcc0PlatFreq(PCC_PCS_VAL(reg));
1395                     break;
1396                 default:
1397                     assert(false);
1398                     break;
1399             }
1400             break;
1401         case 2:
1402             switch (name)
1403             {
1404                 case kCLOCK_Wdog2:
1405                 case kCLOCK_Tpm2:
1406                 case kCLOCK_Tpm3:
1407                 case kCLOCK_Lpi2c2:
1408                 case kCLOCK_Lpi2c3:
1409                 case kCLOCK_I3c1:
1410                 case kCLOCK_Lpuart2:
1411                 case kCLOCK_Lpuart3:
1412                 case kCLOCK_Lpspi2:
1413                 case kCLOCK_Lpspi3:
1414                     freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
1415                     break;
1416                 default:
1417                     assert(false);
1418                     break;
1419             }
1420             break;
1421         case 3:
1422             switch (name)
1423             {
1424                 case kCLOCK_Wdog3:
1425                 case kCLOCK_Wdog4:
1426                 case kCLOCK_Lpit1:
1427                 case kCLOCK_Tpm4:
1428                 case kCLOCK_Tpm5:
1429                 case kCLOCK_Flexio1:
1430                 case kCLOCK_I3c2:
1431                 case kCLOCK_Lpi2c4:
1432                 case kCLOCK_Lpi2c5:
1433                 case kCLOCK_Lpuart4:
1434                 case kCLOCK_Lpuart5:
1435                 case kCLOCK_Lpspi4:
1436                 case kCLOCK_Lpspi5:
1437                     freq = CLOCK_GetPcc3BusFreq(PCC_PCS_VAL(reg));
1438                     break;
1439                 default:
1440                     assert(false);
1441                     break;
1442             }
1443             break;
1444         case 4:
1445             switch (name)
1446             {
1447                 case kCLOCK_Tpm6:
1448                 case kCLOCK_Tpm7:
1449                 case kCLOCK_Lpi2c6:
1450                 case kCLOCK_Lpi2c7:
1451                 case kCLOCK_Lpuart6:
1452                 case kCLOCK_Lpuart7:
1453                     freq = CLOCK_GetPcc4BusFreq(PCC_PCS_VAL(reg));
1454                     break;
1455                 case kCLOCK_Flexspi2:
1456                 case kCLOCK_Usdhc0:
1457                 case kCLOCK_Usdhc1:
1458                 case kCLOCK_Usdhc2:
1459                     freq = CLOCK_GetPcc4PlatFreq(PCC_PCS_VAL(reg));
1460                     break;
1461                 default:
1462                     assert(false);
1463                     break;
1464             }
1465             break;
1466         case 5:
1467             switch (name)
1468             {
1469                 case kCLOCK_Tpm8:
1470                 case kCLOCK_Wdog5:
1471                     freq = CLOCK_GetPcc5BusFreq(PCC_PCS_VAL(reg));
1472                     break;
1473                 case kCLOCK_Csi:
1474                 case kCLOCK_Dsi:
1475                 case kCLOCK_Epdc:
1476                 case kCLOCK_Gpu2d:
1477                 case kCLOCK_Gpu3d:
1478                 case kCLOCK_Dcnano:
1479                 case kCLOCK_CsiClkUi:
1480                 case kCLOCK_CsiClkEsc:
1481                     freq = CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg));
1482                     break;
1483                 default:
1484                     assert(false);
1485                     break;
1486             }
1487             break;
1488         default:
1489             assert(false); /* Not supported */
1490             break;
1491     }
1492 
1493     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
1494 }
1495 
1496 /* Function Name : CLOCK_GetIpFreq */
1497 /*!
1498  * brief Gets the clock frequency for a specific IP module.
1499  *
1500  * This function gets the IP module clock frequency. It is only used for the IP
1501  * modules which could select clock source by CLOCK_SetIpSrc().
1502  *
1503  * param name Which peripheral to get, see \ref clock_ip_name_t.
1504  * return Clock frequency value in hertz
1505  */
CLOCK_GetIpFreq(clock_ip_name_t name)1506 uint32_t CLOCK_GetIpFreq(clock_ip_name_t name)
1507 {
1508     uint32_t reg;
1509     uint32_t freq = 0U;
1510     uint32_t pccIns;
1511 
1512     if (((uint32_t)name & IP_NAME_NON_PCC_FLAG_MASK) == 0UL)
1513     {
1514         /* PCC register */
1515         reg = PCC_REG(name);
1516 
1517         assert((reg & PCC_CLKCFG_PR_MASK) != 0UL);
1518 
1519         if (((uint32_t)name & PCC_PCS_AVAIL_MASK) != 0UL)
1520         {
1521             switch (name)
1522             {
1523                 /* Special case TPM2/3/6/7/8 */
1524                 case kCLOCK_Tpm2:
1525                     freq = CLOCK_GetTpmClkFreq(2);
1526                     break;
1527                 case kCLOCK_Tpm3:
1528                     freq = CLOCK_GetTpmClkFreq(3);
1529                     break;
1530                 case kCLOCK_Tpm6:
1531                     freq = CLOCK_GetTpmClkFreq(6);
1532                     break;
1533                 case kCLOCK_Tpm7:
1534                     freq = CLOCK_GetTpmClkFreq(7);
1535                     break;
1536                 case kCLOCK_Tpm8:
1537                     freq = CLOCK_GetTpmClkFreq(8);
1538                     break;
1539                 default:
1540                     pccIns = CLOCK_GetPccInstance(name);
1541                     freq   = CLOCK_GetPccFreq(pccIns, name, reg);
1542                     break;
1543             }
1544         }
1545         else /* No PCS */
1546         {
1547             switch (name)
1548             {
1549                 case kCLOCK_Sai0:
1550                     freq = CLOCK_GetSaiFreq(0);
1551                     break;
1552                 case kCLOCK_Sai1:
1553                     freq = CLOCK_GetSaiFreq(1);
1554                     break;
1555                 case kCLOCK_Sai2:
1556                     freq = CLOCK_GetSaiFreq(2);
1557                     break;
1558                 case kCLOCK_Sai3:
1559                     freq = CLOCK_GetSaiFreq(3);
1560                     break;
1561                 case kCLOCK_Sai4:
1562                     freq = CLOCK_GetSaiFreq(4);
1563                     break;
1564                 case kCLOCK_Sai5:
1565                     freq = CLOCK_GetSaiFreq(5);
1566                     break;
1567                 case kCLOCK_Sai6:
1568                     freq = CLOCK_GetSaiFreq(6);
1569                     break;
1570                 case kCLOCK_Sai7:
1571                     freq = CLOCK_GetSaiFreq(7);
1572                     break;
1573 
1574                 case kCLOCK_Spdif:
1575                     freq = CLOCK_GetSpdifFreq();
1576                     break;
1577                 case kCLOCK_Micfil:
1578                     freq = CLOCK_GetMicfilFreq();
1579                     break;
1580                 case kCLOCK_Mrt:
1581                     freq = CLOCK_GetMrtFreq();
1582                     break;
1583                 default:
1584                     assert(false);
1585                     freq = 0U;
1586                     break;
1587             }
1588         }
1589     }
1590     else /* Non-PCC IP */
1591     {
1592         if (name == kCLOCK_Mqs0)
1593         {
1594             freq = CLOCK_GetMqsFreq(0);
1595         }
1596         else if (name == kCLOCK_Mqs1)
1597         {
1598             freq = CLOCK_GetMqsFreq(1);
1599         }
1600         else
1601         {
1602             assert(false);
1603         }
1604     }
1605 
1606     return freq;
1607 }
1608 
1609 /*!
1610  * @brief Gets the CGC system clock frequency in RTD.
1611  *
1612  * This function gets the CGC system clock frequency. These clocks are used for
1613  * core, platform, bus and slow clock domains.
1614  *
1615  * @param config   Config value from CGC register.
1616  * @param type     Which type of clock to get.
1617  * @return  Clock frequency.
1618  */
CLOCK_GetRtdSysClkFreq(uint32_t config,cgc_sys_clk_t type)1619 uint32_t CLOCK_GetRtdSysClkFreq(uint32_t config, cgc_sys_clk_t type)
1620 {
1621     uint32_t freq;
1622     cgc_rtd_sys_clk_config_t *pConfig = NULL;
1623     uint32_t sysClkConfig = 0U;
1624 
1625     (void)memcpy((void *)&sysClkConfig, (void *)&config, sizeof(config));
1626     pConfig = (cgc_rtd_sys_clk_config_t *)(uint32_t)&sysClkConfig;
1627 
1628     switch (pConfig->src)
1629     {
1630         case (uint32_t)kCGC_RtdSysClkSrcFro:
1631             freq = CLOCK_GetFroFreq();
1632             break;
1633         case (uint32_t)kCGC_RtdSysClkSrcPll0Pfd0:
1634             freq = CLOCK_GetPll0PfdFreq(kCGC_PllPfd0Clk);
1635             break;
1636         case (uint32_t)kCGC_RtdSysClkSrcPll1Pfd0:
1637             freq = CLOCK_GetPll1PfdFreq(kCGC_PllPfd0Clk);
1638             break;
1639         case (uint32_t)kCGC_RtdSysClkSrcSysOsc:
1640             freq = CLOCK_GetSysOscFreq();
1641             break;
1642         case (uint32_t)kCGC_RtdSysClkSrcRtcOsc:
1643             freq = CLOCK_GetRtcOscFreq();
1644             break;
1645         case (uint32_t)kCGC_RtdSysClkSrcLvds:
1646             freq = CLOCK_GetLvdsClkFreq();
1647             break;
1648         case (uint32_t)kCGC_RtdSysClkSrcPll0:
1649             freq = CLOCK_GetPll0Freq();
1650             break;
1651         default:
1652             freq = 0U;
1653             break;
1654     }
1655 
1656     freq /= (pConfig->divCore + 1U);
1657 
1658     if (kCGC_SysClkSlow == type)
1659     {
1660         freq /= (pConfig->divSlow + 1U);
1661     }
1662     else if (kCGC_SysClkBus == type)
1663     {
1664         freq /= (pConfig->divBus + 1U);
1665     }
1666     else
1667     {
1668         assert(kCGC_SysClkCorePlat == type);
1669     }
1670 
1671     return freq;
1672 }
1673 
1674 /*!
1675  * @brief Gets the CGC CM33 system clock frequency.
1676  *
1677  * This function gets the CGC CM33 system clock frequency. These clocks are used for
1678  * core, platform, bus and slow clock domains.
1679  *
1680  * @param type     Which type of clock to get.
1681  * @return  Clock frequency.
1682  */
CLOCK_GetCm33SysClkFreq(cgc_sys_clk_t type)1683 uint32_t CLOCK_GetCm33SysClkFreq(cgc_sys_clk_t type)
1684 {
1685     return CLOCK_GetRtdSysClkFreq(CGC_RTD->CM33CLK, type);
1686 }
1687 
1688 /*!
1689  * @brief Gets the CGC Fusion DSP system clock frequency.
1690  *
1691  * This function gets the CGC Fusion DSP system clock frequency. These clocks are used for
1692  * core, platform, bus and slow clock domains.
1693  *
1694  * @param type     Which type of clock to get.
1695  * @return  Clock frequency.
1696  */
CLOCK_GetFusionDspSysClkFreq(cgc_sys_clk_t type)1697 uint32_t CLOCK_GetFusionDspSysClkFreq(cgc_sys_clk_t type)
1698 {
1699     return CLOCK_GetRtdSysClkFreq(CGC_RTD->FUSIONCLK, type);
1700 }
1701 
1702 /*!
1703  * brief Initializes the CGC system OSC.
1704  *
1705  * This function enables the CGC system OSC clock according to the
1706  * configuration.
1707  *
1708  * param config   Pointer to the configuration structure.
1709  * retval kStatus_Success System OSC is initialized.
1710  * retval kStatus_CGC_Busy System OSC has been enabled and is used by the system clock.
1711  * retval kStatus_ReadOnly System OSC control register is locked.
1712  *
1713  * note This function can't detect whether the system OSC has been enabled and
1714  * used by an IP.
1715  */
CLOCK_InitSysOsc(const cgc_sosc_config_t * config)1716 status_t CLOCK_InitSysOsc(const cgc_sosc_config_t *config)
1717 {
1718     status_t status;
1719 
1720     assert(config);
1721 
1722     /* De-init the SOSC first. */
1723     status = CLOCK_DeinitSysOsc();
1724 
1725     if (kStatus_Success != status)
1726     {
1727         return status;
1728     }
1729 
1730     /* Now start to set up OSC clock. */
1731     /* Step 1. Set OSC configuration. */
1732     CGC_RTD->SOSCCFG = (uint32_t)(config->workMode);
1733 
1734     /* Step 2. Enable clock. */
1735     CGC_RTD->SOSCCSR = (uint32_t)CGC_SOSCCSR_SOSCEN_MASK | (config->enableMode);
1736 
1737     /* Step 3. Wait for OSC clock to be valid. */
1738     while (0UL == (CGC_RTD->SOSCCSR & CGC_SOSCCSR_SOSCVLD_MASK))
1739     {
1740     }
1741 
1742     /* Step 4. Enabe monitor. */
1743     CGC_RTD->SOSCCSR |= (uint32_t)config->monitorMode;
1744 
1745     return kStatus_Success;
1746 }
1747 
1748 /*!
1749  * brief De-initializes the CGC system OSC.
1750  *
1751  * This function disables the CGC system OSC clock.
1752  *
1753  * retval kStatus_Success System OSC is deinitialized.
1754  * retval kStatus_CGC_Busy System OSC is used by the system clock.
1755  * retval kStatus_ReadOnly System OSC control register is locked.
1756  *
1757  * note This function can't detect whether the system OSC is used by an IP.
1758  */
CLOCK_DeinitSysOsc(void)1759 status_t CLOCK_DeinitSysOsc(void)
1760 {
1761     uint32_t reg = CGC_RTD->SOSCCSR;
1762     status_t status;
1763 
1764     /* If clock is used by system, return error. */
1765     if ((reg & CGC_SOSCCSR_SOSCSEL_MASK) != 0UL)
1766     {
1767         status = kStatus_CGC_Busy;
1768     }
1769     /* If configure register is locked, return error. */
1770     else if ((reg & CGC_SOSCCSR_LK_MASK) != 0UL)
1771     {
1772         status = kStatus_ReadOnly;
1773     }
1774     else
1775     {
1776         CGC_RTD->SOSCCSR = CGC_SOSCCSR_SOSCERR_MASK;
1777         status           = kStatus_Success;
1778     }
1779 
1780     return status;
1781 }
1782 
CLOCK_SetSysOscAsyncClkDiv(volatile uint32_t * pReg,cgc_async_clk_t asyncClk,uint8_t divider)1783 static void CLOCK_SetSysOscAsyncClkDiv(volatile uint32_t *pReg, cgc_async_clk_t asyncClk, uint8_t divider)
1784 {
1785     uint32_t reg = *pReg;
1786 
1787     switch (asyncClk)
1788     {
1789         case kCGC_AsyncDiv3Clk:
1790             reg = (reg & ~(CGC_SOSCDIV_DIV3_MASK | CGC_SOSCDIV_DIV3HALT_MASK)) |
1791                   (divider > 0U ? CGC_SOSCDIV_DIV3((uint32_t)divider - 1U) : CGC_SOSCDIV_DIV3HALT_MASK);
1792             break;
1793         case kCGC_AsyncDiv2Clk:
1794             reg = (reg & ~(CGC_SOSCDIV_DIV2_MASK | CGC_SOSCDIV_DIV2HALT_MASK)) |
1795                   (divider > 0U ? CGC_SOSCDIV_DIV2((uint32_t)divider - 1U) : CGC_SOSCDIV_DIV2HALT_MASK);
1796             break;
1797         case kCGC_AsyncDiv1Clk:
1798             reg = (reg & ~(CGC_SOSCDIV_DIV1_MASK | CGC_SOSCDIV_DIV1HALT_MASK)) |
1799                   (divider > 0U ? CGC_SOSCDIV_DIV1((uint32_t)divider - 1U) : CGC_SOSCDIV_DIV1HALT_MASK);
1800             break;
1801         default:
1802             assert(false);
1803             break;
1804     }
1805 
1806     *pReg = reg;
1807 }
1808 
1809 /*!
1810  * @brief Set the asynchronous clock divider in RTD.
1811  *
1812  * @param asyncClk Which asynchronous clock to configure.
1813  * @param divider The divider value to set. Disabled when divider == 0.
1814  *
1815  * @note There might be glitch when changing the asynchronous divider, so make sure
1816  * the asynchronous clock is not used while changing divider.
1817  */
CLOCK_SetRtdSysOscAsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)1818 void CLOCK_SetRtdSysOscAsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
1819 {
1820     CLOCK_SetSysOscAsyncClkDiv(&CGC_RTD->SOSCDIV, asyncClk, divider);
1821 }
1822 
1823 /*!
1824  * @brief Set the asynchronous clock divider in AD.
1825  *
1826  * @param asyncClk Which asynchronous clock to configure.
1827  * @param divider The divider value to set. Disabled when divider == 0.
1828  *
1829  * @note There might be glitch when changing the asynchronous divider, so make sure
1830  * the asynchronous clock is not used while changing divider.
1831  */
CLOCK_SetAdSysOscAsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)1832 void CLOCK_SetAdSysOscAsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
1833 {
1834     CLOCK_SetSysOscAsyncClkDiv(&CGC_AD->SOSCDIV, asyncClk, divider);
1835 }
1836 
1837 /*!
1838  * @brief Set the asynchronous clock divider in LPAV.
1839  *
1840  * @param asyncClk Which asynchronous clock to configure.
1841  * @param divider The divider value to set. Disabled when divider == 0.
1842  *
1843  * @note There might be glitch when changing the asynchronous divider, so make sure
1844  * the asynchronous clock is not used while changing divider.
1845  */
CLOCK_SetLpavSysOscAsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)1846 void CLOCK_SetLpavSysOscAsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
1847 {
1848     CLOCK_SetSysOscAsyncClkDiv(&CGC_LPAV->SOSCDIV, asyncClk, divider);
1849 }
1850 
1851 /*!
1852  * brief Gets the CGC system OSC clock frequency (SYSOSC).
1853  *
1854  * return  Clock frequency; If the clock is invalid, returns 0.
1855  */
CLOCK_GetSysOscFreq(void)1856 uint32_t CLOCK_GetSysOscFreq(void)
1857 {
1858     uint32_t freq;
1859 
1860     if ((CGC_RTD->SOSCCSR & CGC_SOSCCSR_SOSCVLD_MASK) != 0UL) /* System OSC clock is valid. */
1861     {
1862         /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */
1863         assert(g_xtal0Freq);
1864         freq = g_xtal0Freq;
1865     }
1866     else
1867     {
1868         freq = 0U;
1869     }
1870 
1871     return freq;
1872 }
1873 
CLOCK_GetSysOscAsyncFreq(uint32_t reg,cgc_async_clk_t type)1874 static uint32_t CLOCK_GetSysOscAsyncFreq(uint32_t reg, cgc_async_clk_t type)
1875 {
1876     uint32_t oscFreq = CLOCK_GetSysOscFreq();
1877     uint32_t divider = 0U;
1878     uint32_t freq;
1879 
1880     /* Get divider. */
1881     if (oscFreq != 0UL)
1882     {
1883         switch (type)
1884         {
1885             case kCGC_AsyncDiv3Clk: /* DIV3_CLK. */
1886                 divider = CGC_SOSCDIV_DIV3_VAL(reg);
1887                 break;
1888             case kCGC_AsyncDiv2Clk: /* DIV2_CLK. */
1889                 divider = CGC_SOSCDIV_DIV2_VAL(reg);
1890                 break;
1891             case kCGC_AsyncDiv1Clk: /* DIV1_CLK. */
1892                 divider = CGC_SOSCDIV_DIV1_VAL(reg);
1893                 break;
1894             default:
1895                 assert(false);
1896                 divider = 0U;
1897                 break;
1898         }
1899     }
1900     if (divider != 0UL)
1901     {
1902         freq = oscFreq / divider;
1903     }
1904     else /* Output disabled. */
1905     {
1906         freq = 0U;
1907     }
1908 
1909     return freq;
1910 }
1911 
1912 /*!
1913  * brief Gets the CGC asynchronous clock frequency from the system OSC in RTD.
1914  *
1915  * param type     The asynchronous clock type.
1916  * return  Clock frequency; If the clock is invalid, returns 0.
1917  */
CLOCK_GetRtdSysOscAsyncFreq(cgc_async_clk_t type)1918 uint32_t CLOCK_GetRtdSysOscAsyncFreq(cgc_async_clk_t type)
1919 {
1920     return CLOCK_GetSysOscAsyncFreq(CGC_RTD->SOSCDIV, type);
1921 }
1922 
1923 /*!
1924  * @brief Gets the CGC asynchronous clock frequency from the system OSC in AD.
1925  *
1926  * @param type     The asynchronous clock type.
1927  * @return  Clock frequency; If the clock is invalid, returns 0.
1928  */
CLOCK_GetAdSysOscAsyncFreq(cgc_async_clk_t type)1929 uint32_t CLOCK_GetAdSysOscAsyncFreq(cgc_async_clk_t type)
1930 {
1931     return CLOCK_GetSysOscAsyncFreq(CGC_AD->SOSCDIV, type);
1932 }
1933 
1934 /*!
1935  * @brief Gets the CGC asynchronous clock frequency from the system OSC in LPAV.
1936  *
1937  * @param type     The asynchronous clock type.
1938  * @return  Clock frequency; If the clock is invalid, returns 0.
1939  */
CLOCK_GetLpavSysOscAsyncFreq(cgc_async_clk_t type)1940 uint32_t CLOCK_GetLpavSysOscAsyncFreq(cgc_async_clk_t type)
1941 {
1942     return CLOCK_GetSysOscAsyncFreq(CGC_LPAV->SOSCDIV, type);
1943 }
1944 
1945 /*!
1946  * brief Initializes the CGC FRO clock.
1947  *
1948  * This function initializes the CGC FRO clock according to the
1949  * configuration.
1950  *
1951  * param config   Pointer to the configuration structure.
1952  * retval kStatus_Success FRO is initialized.
1953  * retval kStatus_CGC_Busy FRO has been enabled and is used by system clock.
1954  * retval kStatus_ReadOnly FRO control register is locked.
1955  *
1956  * note This function can't detect whether the FRO has been enabled and
1957  * used by an IP.
1958  */
CLOCK_InitFro(const cgc_fro_config_t * config)1959 status_t CLOCK_InitFro(const cgc_fro_config_t *config)
1960 {
1961     status_t status;
1962 
1963     assert(config);
1964 
1965     /* De-init the FRO first. */
1966     status = CLOCK_DeinitFro();
1967 
1968     if (kStatus_Success != status)
1969     {
1970         return status;
1971     }
1972 
1973     /* Now start to set up FRO clock. */
1974     /* Step 1. Configure clock. */
1975     CGC_RTD->FROCSR = (uint32_t)config->enableMode;
1976 
1977     /* Step 2. Wait for FRO clock to be valid. */
1978     while (0UL == (CGC_RTD->FROCSR & CGC_FROCSR_FROVLD_MASK))
1979     {
1980     }
1981 
1982     return kStatus_Success;
1983 }
1984 
1985 /*!
1986  * brief De-initializes the CGC FRO.
1987  *
1988  * This function deinitializes the CGC FRO.
1989  *
1990  * retval kStatus_Success FRO is deinitialized.
1991  * retval kStatus_CGC_Busy FRO is used by system clock.
1992  * retval kStatus_ReadOnly FRO control register is locked.
1993  *
1994  * note This function can't detect whether the FRO is used by an IP.
1995  */
CLOCK_DeinitFro(void)1996 status_t CLOCK_DeinitFro(void)
1997 {
1998     uint32_t reg = CGC_RTD->FROCSR;
1999     status_t status;
2000 
2001     /* If clock is used by system, return error. */
2002     if ((reg & CGC_FROCSR_FROSEL_MASK) != 0UL)
2003     {
2004         status = kStatus_CGC_Busy;
2005     }
2006     /* If configure register is locked, return error. */
2007     else if ((reg & CGC_FROCSR_LK_MASK) != 0UL)
2008     {
2009         status = kStatus_ReadOnly;
2010     }
2011     else
2012     {
2013         CGC_RTD->FROCSR = 0U;
2014         status          = kStatus_Success;
2015     }
2016 
2017     return status;
2018 }
2019 
CLOCK_SetFroAsyncClkDiv(volatile uint32_t * pReg,cgc_async_clk_t asyncClk,uint8_t divider)2020 static void CLOCK_SetFroAsyncClkDiv(volatile uint32_t *pReg, cgc_async_clk_t asyncClk, uint8_t divider)
2021 {
2022     uint32_t reg = *pReg;
2023 
2024     switch (asyncClk)
2025     {
2026         case kCGC_AsyncDiv3Clk:
2027             reg = (reg & ~(CGC_FRODIV_DIV3_MASK | CGC_FRODIV_DIV3HALT_MASK)) |
2028                   (divider > 0U ? CGC_FRODIV_DIV3((uint32_t)divider - 1U) : CGC_FRODIV_DIV3HALT_MASK);
2029             break;
2030         case kCGC_AsyncDiv2Clk:
2031             reg = (reg & ~(CGC_FRODIV_DIV2_MASK | CGC_FRODIV_DIV2HALT_MASK)) |
2032                   (divider > 0U ? CGC_FRODIV_DIV2((uint32_t)divider - 1U) : CGC_FRODIV_DIV2HALT_MASK);
2033             break;
2034         case kCGC_AsyncDiv1Clk:
2035             reg = (reg & ~(CGC_FRODIV_DIV1_MASK | CGC_FRODIV_DIV1HALT_MASK)) |
2036                   (divider > 0U ? CGC_FRODIV_DIV1((uint32_t)divider - 1U) : CGC_FRODIV_DIV1HALT_MASK);
2037             break;
2038         default:
2039             assert(false);
2040             break;
2041     }
2042 
2043     *pReg = reg;
2044 }
2045 
2046 /*!
2047  * @brief Set the asynchronous clock divider in RTD.
2048  *
2049  * @param asyncClk Which asynchronous clock to configure.
2050  * @param divider The divider value to set. Disabled when divider == 0.
2051  *
2052  * @note There might be glitch when changing the asynchronous divider, so make sure
2053  * the asynchronous clock is not used while changing divider.
2054  */
CLOCK_SetRtdFroAsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)2055 void CLOCK_SetRtdFroAsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
2056 {
2057     CLOCK_SetFroAsyncClkDiv(&CGC_RTD->FRODIV, asyncClk, divider);
2058 }
2059 
2060 /*!
2061  * @brief Set the asynchronous clock divider in AD.
2062  *
2063  * @param asyncClk Which asynchronous clock to configure.
2064  * @param divider The divider value to set. Disabled when divider == 0.
2065  *
2066  * @note There might be glitch when changing the asynchronous divider, so make sure
2067  * the asynchronous clock is not used while changing divider.
2068  */
CLOCK_SetAdFroAsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)2069 void CLOCK_SetAdFroAsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
2070 {
2071     CLOCK_SetFroAsyncClkDiv(&CGC_AD->FRODIV, asyncClk, divider);
2072 }
2073 
2074 /*!
2075  * @brief Set the asynchronous clock divider in LPAV.
2076  *
2077  * @param asyncClk Which asynchronous clock to configure.
2078  * @param divider The divider value to set. Disabled when divider == 0.
2079  *
2080  * @note There might be glitch when changing the asynchronous divider, so make sure
2081  * the asynchronous clock is not used while changing divider.
2082  */
CLOCK_SetLpavFroAsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)2083 void CLOCK_SetLpavFroAsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
2084 {
2085     CLOCK_SetFroAsyncClkDiv(&CGC_LPAV->FRODIV, asyncClk, divider);
2086 }
2087 
2088 /*! @brief  Enable/Disable FRO tuning.
2089  *   On enable, the function will wait until FRO is close to the target frequency.
2090  */
CLOCK_EnableFroTuning(bool enable)2091 void CLOCK_EnableFroTuning(bool enable)
2092 {
2093     uint32_t xtalFreq   = CLOCK_GetSysOscFreq();
2094     uint64_t targetFreq = CLK_FRO_192MHZ / 4U;
2095     uint32_t expected, up, low;
2096     uint32_t captured, trim;
2097 
2098     assert(xtalFreq);
2099     assert(targetFreq > xtalFreq);
2100 
2101     if (enable)
2102     {
2103         expected = (uint32_t)((targetFreq * (2047U * 2U + 1U) / xtalFreq + 6U) / 2U);
2104         up       = (uint32_t)(targetFreq * 2047U * 100085U / xtalFreq / 100000U + 2U);
2105         low      = (uint32_t)((targetFreq * 2048U * 99915U + (uint64_t)xtalFreq * 100000U) / xtalFreq / 100000U + 3U);
2106 
2107         /* Start tuning */
2108         CGC_RTD->FROCTRL = CGC_FROCTRL_EXP_COUNT(expected) | CGC_FROCTRL_THRESH_RANGE_UP(up - expected) |
2109                            CGC_FROCTRL_THRESH_RANGE_LOW(expected - low) | CGC_FROCTRL_ENA_TUNE_MASK;
2110 
2111         while (true)
2112         {
2113             while ((CGC_RTD->FROCAPVAL & CGC_FROCAPVAL_DATA_VALID_MASK) == 0UL)
2114             {
2115             }
2116 
2117             captured = CGC_RTD->FROCAPVAL & CGC_FROCAPVAL_CAPVAL_MASK;
2118             trim     = CGC_RTD->FRORDTRIM;
2119             /* Clear FRO_CAPVAL VALID flag */
2120             CGC_RTD->FRORDTRIM = trim;
2121             /* Reach the frequency range, then return. */
2122             if ((captured <= up) && (captured >= low))
2123             {
2124                 break;
2125             }
2126         }
2127     }
2128     else
2129     {
2130         CGC_RTD->FROCTRL &= ~CGC_FROCTRL_ENA_TUNE_MASK;
2131     }
2132 }
2133 
2134 /*!
2135  * brief Gets the CGC FRO clock frequency.
2136  *
2137  * return  Clock frequency; If the clock is invalid, returns 0.
2138  */
CLOCK_GetFroFreq(void)2139 uint32_t CLOCK_GetFroFreq(void)
2140 {
2141     uint32_t freq;
2142 
2143     if ((CGC_RTD->FROCSR & CGC_FROCSR_FROVLD_MASK) != 0UL) /* FRO is valid. */
2144     {
2145         freq = CLK_FRO_192MHZ;
2146     }
2147     else
2148     {
2149         freq = 0U;
2150     }
2151 
2152     return freq;
2153 }
2154 
CLOCK_GetFroAsyncFreq(uint32_t reg,cgc_async_clk_t type)2155 static uint32_t CLOCK_GetFroAsyncFreq(uint32_t reg, cgc_async_clk_t type)
2156 {
2157     uint32_t froFreq = CLOCK_GetFroFreq();
2158     uint32_t divider = 0U;
2159     uint32_t freq;
2160 
2161     /* Get divider. */
2162     if (froFreq != 0UL)
2163     {
2164         switch (type)
2165         {
2166             case kCGC_AsyncDiv3Clk: /* DIV3_CLK. */
2167                 divider = CGC_FRODIV_DIV3_VAL(reg);
2168                 break;
2169             case kCGC_AsyncDiv2Clk: /* DIV2_CLK. */
2170                 divider = CGC_FRODIV_DIV2_VAL(reg);
2171                 break;
2172             case kCGC_AsyncDiv1Clk: /* DIV2_CLK. */
2173                 divider = CGC_FRODIV_DIV1_VAL(reg);
2174                 break;
2175             default:
2176                 divider = 0U;
2177                 break;
2178         }
2179     }
2180     if (divider != 0UL)
2181     {
2182         freq = froFreq / divider;
2183     }
2184     else /* Output disabled. */
2185     {
2186         freq = 0U;
2187     }
2188 
2189     return freq;
2190 }
2191 
2192 /*!
2193  * brief Gets the CGC asynchronous clock frequency from the FRO in RTD.
2194  *
2195  * param type     The asynchronous clock type.
2196  * return  Clock frequency; If the clock is invalid, returns 0.
2197  */
CLOCK_GetRtdFroAsyncFreq(cgc_async_clk_t type)2198 uint32_t CLOCK_GetRtdFroAsyncFreq(cgc_async_clk_t type)
2199 {
2200     return CLOCK_GetFroAsyncFreq(CGC_RTD->FRODIV, type);
2201 }
2202 
2203 /*!
2204  * brief Gets the CGC asynchronous clock frequency from the FRO in AD.
2205  *
2206  * param type     The asynchronous clock type.
2207  * return  Clock frequency; If the clock is invalid, returns 0.
2208  */
CLOCK_GetAdFroAsyncFreq(cgc_async_clk_t type)2209 uint32_t CLOCK_GetAdFroAsyncFreq(cgc_async_clk_t type)
2210 {
2211     return CLOCK_GetFroAsyncFreq(CGC_AD->FRODIV, type);
2212 }
2213 
2214 /*!
2215  * brief Gets the CGC asynchronous clock frequency from the FRO in LPAV.
2216  *
2217  * param type     The asynchronous clock type.
2218  * return  Clock frequency; If the clock is invalid, returns 0.
2219  */
CLOCK_GetLpavFroAsyncFreq(cgc_async_clk_t type)2220 uint32_t CLOCK_GetLpavFroAsyncFreq(cgc_async_clk_t type)
2221 {
2222     return CLOCK_GetFroAsyncFreq(CGC_LPAV->FRODIV, type);
2223 }
2224 
2225 /*!
2226  * @brief Initializes the CGC LPOSC clock.
2227  *
2228  * This function initializes the CGC LPOSC clock according to the
2229  * configuration.
2230  *
2231  * @param config   Pointer to the configuration structure.
2232  * @retval kStatus_Success LPOSC is initialized.
2233  * @retval kStatus_ReadOnly FRO control register is locked.
2234  *
2235  * @note This function can't detect whether the LPOSC has been enabled and
2236  * used by an IP.
2237  */
CLOCK_InitLposc(const cgc_lposc_config_t * config)2238 status_t CLOCK_InitLposc(const cgc_lposc_config_t *config)
2239 {
2240     status_t status;
2241 
2242     assert(config);
2243 
2244     /* De-init the FRO first. */
2245     status = CLOCK_DeinitLposc();
2246 
2247     if (kStatus_Success != status)
2248     {
2249         return status;
2250     }
2251 
2252     /* Now start to set up LPOSC clock. */
2253     /* Step 1. Configure clock. */
2254     CGC_RTD->LPOSCCSR = CGC_LPOSCCSR_LPOSCEN_MASK | config->enableMode;
2255 
2256     /* Step 2. Wait for FRO clock to be valid. */
2257     while (0UL == (CGC_RTD->LPOSCCSR & CGC_LPOSCCSR_LPOSCVLD_MASK))
2258     {
2259     }
2260 
2261     return kStatus_Success;
2262 }
2263 
2264 /*!
2265  * @brief De-initializes the CGC LPOSC.
2266  *
2267  * This function deinitializes the CGC LPOSC.
2268  *
2269  * @retval kStatus_Success LPOSC is deinitialized.
2270  * @retval kStatus_ReadOnly LPOSC control register is locked.
2271  *
2272  * @note This function can't detect whether the LPOSC is used by an IP.
2273  */
CLOCK_DeinitLposc(void)2274 status_t CLOCK_DeinitLposc(void)
2275 {
2276     uint32_t reg = CGC_RTD->LPOSCCSR;
2277     status_t status;
2278 
2279     /* If configure register is locked, return error. */
2280     if ((reg & CGC_LPOSCCSR_LK_MASK) != 0UL)
2281     {
2282         status = kStatus_ReadOnly;
2283     }
2284     else
2285     {
2286         CGC_RTD->LPOSCCSR = 0U;
2287         status            = kStatus_Success;
2288     }
2289 
2290     return status;
2291 }
2292 
2293 /*!
2294  * @brief Gets the CGC LPOSC clock frequency.
2295  *
2296  * @return  Clock frequency; If the clock is invalid, returns 0.
2297  */
CLOCK_GetLpOscFreq(void)2298 uint32_t CLOCK_GetLpOscFreq(void)
2299 {
2300     uint32_t freq;
2301 
2302     if ((CGC_RTD->LPOSCCSR & CGC_LPOSCCSR_LPOSCVLD_MASK) != 0UL) /* LPOSC is valid. */
2303     {
2304         freq = CLK_LPOSC_1MHZ;
2305     }
2306     else
2307     {
2308         freq = 0U;
2309     }
2310 
2311     return freq;
2312 }
2313 
2314 /*!
2315  * brief Gets the CGC RTC OSC clock frequency.
2316  *
2317  * return  Clock frequency; If the clock is invalid, returns 0.
2318  */
CLOCK_GetRtcOscFreq(void)2319 uint32_t CLOCK_GetRtcOscFreq(void)
2320 {
2321     uint32_t freq;
2322 
2323     if ((CGC_RTD->ROSCCTRL & CGC_ROSCCTRL_ROSCVLD_MASK) != 0UL) /* RTC OSC clock is valid. */
2324     {
2325         /* Please call CLOCK_SetXtal32Freq base on board setting before using RTC OSC clock. */
2326         assert(g_xtal32Freq);
2327         freq = g_xtal32Freq;
2328     }
2329     else
2330     {
2331         freq = 0U;
2332     }
2333 
2334     return freq;
2335 }
2336 
2337 /*!
2338  * @brief Sets the RTC OSC monitor mode.
2339  *
2340  * This function sets the RTC OSC monitor mode. The mode can be disabled.
2341  * It can generate an interrupt when the error is disabled, or reset when the error is detected.
2342  *
2343  * @param mode Monitor mode to set.
2344  */
CLOCK_SetRtcOscMonitorMode(cgc_rosc_monitor_mode_t mode)2345 void CLOCK_SetRtcOscMonitorMode(cgc_rosc_monitor_mode_t mode)
2346 {
2347     uint32_t reg = CGC_RTD->ROSCCTRL;
2348 
2349     reg &= ~(CGC_ROSCCTRL_ROSCCM_MASK | CGC_ROSCCTRL_ROSCCMRE_MASK);
2350 
2351     reg |= (uint32_t)mode;
2352 
2353     CGC_RTD->ROSCCTRL = reg;
2354 }
2355 
2356 /*!
2357  * @brief Initializes the CGC PLL0.
2358  *
2359  * This function enables the CGC PLL0 clock according to the
2360  * configuration. The PLL0 can use the OSC or FRO as
2361  * the clock source. Ensure that the source clock is valid before
2362  * calling this function.
2363  *
2364  * Example code for initializing PLL0 clock output:
2365  * @code
2366  * const cgc_pll0_config_t g_cgcPll0Config = {.enableMode = kCGC_PllEnable,
2367  *                                            .div1 = 1U,
2368  *                                            .pfd1Div = 2U,
2369  *                                            .pfd2Div = 0U,
2370  *                                            .src = kCGC_PllSrcSysOsc,
2371  *                                            .mult = kCGC_Pll0Mult20};
2372  * CLOCK_InitPll0(&g_cgcPll0Config);
2373  * @endcode
2374  *
2375  * @param config   Pointer to the configuration structure.
2376  * @retval kStatus_Success PLL0 is initialized.
2377  * @retval kStatus_CGC_Busy PLL0 has been enabled and is used by the system clock.
2378  * @retval kStatus_ReadOnly PLL0 control register is locked.
2379  *
2380  * @note This function can't detect whether the PLL0 has been enabled and
2381  * used by an IP.
2382  */
CLOCK_InitPll0(const cgc_pll0_config_t * config)2383 status_t CLOCK_InitPll0(const cgc_pll0_config_t *config)
2384 {
2385     status_t status;
2386 
2387     assert(config);
2388 
2389     /* De-init the PLL0 first. */
2390     status = CLOCK_DeinitPll0();
2391 
2392     if (kStatus_Success != status)
2393     {
2394         return status;
2395     }
2396 
2397     /* Now start to set up PLL clock. */
2398     /* Step 1. Setup dividers. */
2399     CGC_RTD->PLL0DIV_VCO =
2400         config->div1 > 0U ? CGC_PLL0DIV_VCO_DIV1((uint32_t)config->div1 - 1U) : (uint32_t)CGC_PLL0DIV_VCO_DIV1HALT_MASK;
2401     CGC_RTD->PLL0DIV_PFD_0 = (config->pfd1Div > 0U ? CGC_PLL0DIV_PFD_0_DIV1((uint32_t)config->pfd1Div - 1U) :
2402                                                      (uint32_t)CGC_PLL0DIV_PFD_0_DIV1HALT_MASK) |
2403                              (config->pfd2Div > 0U ? CGC_PLL0DIV_PFD_0_DIV2((uint32_t)config->pfd2Div - 1U) :
2404                                                      (uint32_t)CGC_PLL0DIV_PFD_0_DIV2HALT_MASK);
2405 
2406     /* Step 2. Set PLL configuration. */
2407     CGC_RTD->PLL0CFG = CGC_PLL0CFG_SOURCE(config->src) | CGC_PLL0CFG_MULT(config->mult);
2408 
2409     /* Step 3. Enable clock. */
2410     CGC_RTD->PLL0CSR = (uint32_t)CGC_PLL0CSR_PLL0EN_MASK | config->enableMode;
2411 
2412     /* Step 4. Wait for PLL clock to be valid. */
2413     while (0UL == (CGC_RTD->PLL0CSR & CGC_PLL0CSR_PLLVLD_MASK))
2414     {
2415     }
2416 
2417     return kStatus_Success;
2418 }
2419 
2420 /*!
2421  * brief De-initializes the CGC system PLL.
2422  *
2423  * This function disables the CGC system PLL.
2424  *
2425  * retval kStatus_Success system PLL is deinitialized.
2426  * retval kStatus_CGC_Busy system PLL is used by the system clock.
2427  * retval kStatus_ReadOnly PLL0 control register is locked.
2428  *
2429  * note This function can't detect whether the system PLL is used by an IP.
2430  */
CLOCK_DeinitPll0(void)2431 status_t CLOCK_DeinitPll0(void)
2432 {
2433     uint32_t reg = CGC_RTD->PLL0CSR;
2434     status_t status;
2435 
2436     /* If clock is used by system, return error. */
2437     if ((reg & CGC_PLL0CSR_PLLSEL_MASK) != 0UL)
2438     {
2439         status = kStatus_CGC_Busy;
2440     }
2441     /* If configure register is locked, return error. */
2442     else if ((reg & CGC_PLL0CSR_LK_MASK) != 0UL)
2443     {
2444         status = kStatus_ReadOnly;
2445     }
2446     else
2447     {
2448         CGC_RTD->PLL0CSR = 0;
2449         status           = kStatus_Success;
2450     }
2451 
2452     return status;
2453 }
2454 
2455 /*!
2456  * @brief Set the asynchronous clock divider.
2457  *
2458  * @param asyncClk Which asynchronous clock to configure.
2459  * @param divider The divider value to set. Disabled when divider == 0.
2460  *
2461  * @note There might be glitch when changing the asynchronous divider, so make sure
2462  * the asynchronous clock is not used while changing divider.
2463  */
CLOCK_SetPll0AsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)2464 void CLOCK_SetPll0AsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
2465 {
2466     uint32_t reg;
2467 
2468     switch (asyncClk)
2469     {
2470         case kCGC_AsyncVcoClk:
2471             reg = CGC_RTD->PLL0DIV_VCO;
2472             reg =
2473                 (reg & ~(CGC_PLL0DIV_VCO_DIV1_MASK | CGC_PLL0DIV_VCO_DIV1HALT_MASK)) |
2474                 (divider > 0U ? CGC_PLL0DIV_VCO_DIV1((uint32_t)divider - 1U) : (uint32_t)CGC_PLL0DIV_VCO_DIV1HALT_MASK);
2475             CGC_RTD->PLL0DIV_VCO = reg;
2476             break;
2477         case kCGC_AsyncPfd1Div1Clk:
2478             reg = CGC_RTD->PLL0DIV_PFD_0;
2479             reg = (reg & ~(CGC_PLL0DIV_PFD_0_DIV1_MASK | CGC_PLL0DIV_PFD_0_DIV1HALT_MASK)) |
2480                   (divider > 0U ? CGC_PLL0DIV_PFD_0_DIV1((uint32_t)divider - 1U) :
2481                                   (uint32_t)CGC_PLL0DIV_PFD_0_DIV1HALT_MASK);
2482             CGC_RTD->PLL0DIV_PFD_0 = reg;
2483             break;
2484         case kCGC_AsyncPfd2Div1Clk:
2485             reg = CGC_RTD->PLL0DIV_PFD_0;
2486             reg = (reg & ~(CGC_PLL0DIV_PFD_0_DIV2_MASK | CGC_PLL0DIV_PFD_0_DIV2HALT_MASK)) |
2487                   (divider > 0U ? CGC_PLL0DIV_PFD_0_DIV2((uint32_t)divider - 1U) :
2488                                   (uint32_t)CGC_PLL0DIV_PFD_0_DIV2HALT_MASK);
2489             CGC_RTD->PLL0DIV_PFD_0 = reg;
2490             break;
2491         default:
2492             assert(false);
2493             break;
2494     }
2495 }
2496 
CLOCK_GetPll0CommonFreq(void)2497 static uint32_t CLOCK_GetPll0CommonFreq(void)
2498 {
2499     uint32_t freq = 0U;
2500 
2501     if ((CGC_RTD->PLL0CFG & CGC_PLL0CFG_SOURCE_MASK) != 0UL) /* If use FRO24M */
2502     {
2503         freq = CLOCK_GetFroFreq() / 8U;
2504     }
2505     else /* Use System OSC. */
2506     {
2507         freq = CLOCK_GetSysOscFreq();
2508     }
2509 
2510     if (freq != 0UL) /* If source is valid. */
2511     {
2512         freq *= s_pll0Multi[CGC_PLL0CFG_MULT_VAL]; /* Multiplier. */
2513     }
2514 
2515     return freq;
2516 }
2517 
2518 /*!
2519  * brief Gets the CGC system PLL clock frequency.
2520  *
2521  * return  Clock frequency; If the clock is invalid, returns 0.
2522  */
CLOCK_GetPll0Freq(void)2523 uint32_t CLOCK_GetPll0Freq(void)
2524 {
2525     uint32_t freq;
2526 
2527     if ((CGC_RTD->PLL0CSR & CGC_PLL0CSR_PLLVLD_MASK) != 0UL) /* PLL0 is valid. */
2528     {
2529         freq = CLOCK_GetPll0CommonFreq();
2530     }
2531     else
2532     {
2533         freq = 0U;
2534     }
2535 
2536     return freq;
2537 }
2538 
2539 /*!
2540  * brief Gets the CGC asynchronous clock frequency from PLL0.
2541  *
2542  * param type     The asynchronous clock type.
2543  * return  Clock frequency; If the clock is invalid, returns 0.
2544  */
CLOCK_GetPll0AsyncFreq(cgc_async_clk_t type)2545 uint32_t CLOCK_GetPll0AsyncFreq(cgc_async_clk_t type)
2546 {
2547     uint32_t pllFreq;
2548     uint32_t divider;
2549     uint32_t freq;
2550 
2551     switch (type)
2552     {
2553         case kCGC_AsyncVcoClk: /* PLL0 VCO. */
2554             pllFreq = CLOCK_GetPll0Freq();
2555             divider = CGC_PLL0DIV_VCO_DIV1_VAL;
2556             break;
2557         case kCGC_AsyncPfd1Div1Clk: /* PLL0 PFD1 DIV. */
2558             pllFreq = CLOCK_GetPll0PfdFreq(kCGC_PllPfd1Clk);
2559             divider = CGC_PLL0DIV_PFD1_DIV_VAL;
2560             break;
2561         case kCGC_AsyncPfd2Div1Clk: /* PLL0 PFD2 DIV. */
2562             pllFreq = CLOCK_GetPll0PfdFreq(kCGC_PllPfd2Clk);
2563             divider = CGC_PLL0DIV_PFD2_DIV_VAL;
2564             break;
2565         default:
2566             divider = 0U;
2567             assert(false);
2568             break;
2569     }
2570 
2571     if (divider != 0UL)
2572     {
2573         freq = pllFreq / divider;
2574     }
2575     else /* Output disabled. */
2576     {
2577         freq = 0U;
2578     }
2579 
2580     return freq;
2581 }
2582 
2583 /*!
2584  * @brief Gets the CGC PLL0 PFD clock frequency.
2585  *
2586  * @param pfdClkout     The selected PFD clock out. See "cgc_pll_pfd_clkout_t".
2587  * @return  Clock frequency; If the clock is invalid, returns 0.
2588  */
CLOCK_GetPll0PfdFreq(cgc_pll_pfd_clkout_t pfdClkout)2589 uint32_t CLOCK_GetPll0PfdFreq(cgc_pll_pfd_clkout_t pfdClkout)
2590 {
2591     uint32_t freq      = 0U;
2592     uint32_t fracValue = 0U;
2593 
2594     if ((CGC_RTD->PLL0PFDCFG & CGC_PLLPFD_PFD_VALID_MASK(pfdClkout)) != 0UL) /* PLL0 PFD is valid. */
2595     {
2596         if (0UL == (CGC_RTD->PLL0PFDCFG & CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout)))
2597         {
2598             fracValue = (CGC_RTD->PLL0PFDCFG & CGC_PLLPFD_PFD_MASK(pfdClkout)) >> (uint32_t)pfdClkout;
2599 
2600             if (fracValue != 0UL)
2601             {
2602                 freq = CLOCK_GetPll0CommonFreq();
2603                 freq = (uint32_t)((uint64_t)freq * PFD_FREQ_CALCUL_CONSTANT /
2604                                   fracValue); /* PFD Clock Frequency = PLL output frequency * 18 / frac value. */
2605             }
2606             else
2607             {
2608             }
2609         }
2610         else
2611         {
2612         }
2613     }
2614     else
2615     {
2616     }
2617 
2618     return freq;
2619 }
2620 
2621 /*!
2622  * @brief Enables the CGC PLL0 Fractional Divide (PFD) clock out with configurations.
2623  *
2624  * PLL Frequency = Fref * MULT
2625  * PFD Clock Frequency = PLL output frequency * 18/frac value
2626  *
2627  * @code
2628  * Example code for configuring PLL0 PFD0 clock output:
2629  * const cgc_pll0_config_t g_cgcPll0Config = {.enableMode = kCGC_PllEnable,
2630  *                                           .div1 = 1U,
2631  *                                           .pfd1Div = 2U,
2632  *                                           .pfd2Div = 0U,
2633  *                                           .src = kCGC_PllSrcSysOsc,
2634  *                                           .mult = kCGC_Pll0Mult20};
2635  * CLOCK_InitPll0(&g_cgcPll0Config);
2636  * CLOCK_EnablePll0PfdClkout(kCGC_PllPfd0Clk, 15U);
2637  * @endcode
2638  *
2639  * @param pfdClkout  PLL0 PFD clock out select.
2640  * @param fracValue  Fractional Divider value. Recommended to be kept between 12-35 for all PFDs.
2641  */
CLOCK_EnablePll0PfdClkout(cgc_pll_pfd_clkout_t pfdClkout,uint8_t fracValue)2642 void CLOCK_EnablePll0PfdClkout(cgc_pll_pfd_clkout_t pfdClkout, uint8_t fracValue)
2643 {
2644     /*
2645      * Input fractional divider value should have a maximum size of 6 bits (64U).
2646      * Note: It is recommended that PFD settings are kept between 12-35 for all PFDs.
2647      */
2648     assert(fracValue);
2649     assert(fracValue < CGC_PLLPFD_PFD_MAX_VAL);
2650 
2651     /* Step 1. Gate PFD clock. */
2652     CGC_RTD->PLL0PFDCFG |= CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout);
2653 
2654     /* Step 2. Program the new PFD value. */
2655     CGC_RTD->PLL0PFDCFG =
2656         (CGC_RTD->PLL0PFDCFG & ~CGC_PLLPFD_PFD_MASK(pfdClkout)) | CGC_PLLPFD_PFD_VAL(pfdClkout, fracValue);
2657 
2658     /* Step 3. Ungate PFD clock. */
2659     CGC_RTD->PLL0PFDCFG &= ~CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout);
2660 
2661     /* Step 4. Wait for PFD clock to be stable. */
2662     while (0UL == (CGC_RTD->PLL0PFDCFG & CGC_PLLPFD_PFD_VALID_MASK(pfdClkout)))
2663     {
2664     }
2665 }
2666 
2667 /*!
2668  * @brief Initializes the CGC PLL1.
2669  *
2670  * This function enables the CGC PLL1 clock according to the
2671  * configuration. The PLL1 can use the system OSC or FRO as
2672  * the clock source. Ensure that the source clock is valid before
2673  * calling this function.
2674  *
2675  * Example code for initializing PLL1 clock output:
2676  * @code
2677  * const cgc_pll1_config_t g_cgcPll1Config = {.enableMode = kCGC_PllEnable,
2678  *                                            .div1 = 0U,
2679  *                                            .pfd1Div = 0U,
2680  *                                            .pfd2Div = 0U,
2681  *                                            .src = kCGC_PllSrcFro24M,
2682  *                                            .mult = kCGC_Pll1Mult22,
2683  *                                            .num = 578,
2684  *                                            .denom = 1000};
2685  * CLOCK_InitPll1(&g_cgcPll1Config);
2686  * @endcode
2687  *
2688  * @param config   Pointer to the configuration structure.
2689  * @retval kStatus_Success PLL1 is initialized.
2690  * @retval kStatus_CGC_Busy PLL1 has been enabled and is used by the system clock.
2691  * @retval kStatus_ReadOnly PLL1 control register is locked.
2692  *
2693  * @note This function can't detect whether the PLL1 has been enabled and
2694  * is used by an IP.
2695  */
CLOCK_InitPll1(const cgc_pll1_config_t * config)2696 status_t CLOCK_InitPll1(const cgc_pll1_config_t *config)
2697 {
2698     status_t status;
2699 
2700     assert(config);
2701 
2702     /* De-init the PLL1 first. */
2703     status = CLOCK_DeinitPll1();
2704     if (kStatus_Success != status)
2705     {
2706         return status;
2707     }
2708 
2709     /* Now start to set up PLL clock. */
2710     /* Step 1. Setup dividers. */
2711     CGC_RTD->PLL1DIV_VCO =
2712         (config->div1 > 0U ? CGC_PLL1DIV_VCO_DIV1((uint32_t)config->div1 - 1U) : CGC_PLL1DIV_VCO_DIV1HALT_MASK);
2713     CGC_RTD->PLL1DIV_PFD_0 = (config->pfd1Div > 0U ? CGC_PLL1DIV_PFD_0_DIV1((uint32_t)config->pfd1Div - 1U) :
2714                                                      (uint32_t)CGC_PLL1DIV_PFD_0_DIV1HALT_MASK) |
2715                              (config->pfd2Div > 0U ? CGC_PLL1DIV_PFD_0_DIV2((uint32_t)config->pfd2Div - 1U) :
2716                                                      (uint32_t)CGC_PLL1DIV_PFD_0_DIV2HALT_MASK);
2717 
2718     /* Step 2. Set PLL configuration. */
2719     CGC_RTD->PLL1CFG = CGC_PLL1CFG_SOURCE(config->src) | CGC_PLL1CFG_MULT(config->mult);
2720 
2721     /* Step 3. Set Numerator and Denominator. */
2722     CGC_RTD->PLL1DENOM = config->denom;
2723     CGC_RTD->PLL1NUM   = config->num;
2724 
2725     /* Step 4. Enable clock. */
2726     CGC_RTD->PLL1CSR = (uint32_t)CGC_PLL1CSR_PLLEN_MASK | config->enableMode;
2727 
2728     /* Step 5. Wait for PLL clock to be valid. */
2729     while (0UL == (CGC_RTD->PLL1CSR & CGC_PLL1CSR_PLLVLD_MASK))
2730     {
2731     }
2732 
2733     return kStatus_Success;
2734 }
2735 
2736 /*!
2737  * @brief De-initializes the CGC PLL1.
2738  *
2739  * This function disables the CGC PLL1.
2740  *
2741  * @retval kStatus_Success PLL1 is deinitialized.
2742  * @retval kStatus_CGC_Busy PLL1 is used by the system clock.
2743  * @retval kStatus_ReadOnly PLL1 control register is locked.
2744  *
2745  * @note This function can't detect whether the PLL1 is used by an IP.
2746  */
CLOCK_DeinitPll1(void)2747 status_t CLOCK_DeinitPll1(void)
2748 {
2749     uint32_t reg = CGC_RTD->PLL1CSR;
2750     status_t status;
2751 
2752     /* If clock is used by system, return error. */
2753     if ((reg & CGC_PLL1CSR_PLLSEL_MASK) != 0UL)
2754     {
2755         status = kStatus_CGC_Busy;
2756     }
2757     /* If configure register is locked, return error. */
2758     else if ((reg & CGC_PLL1CSR_LK_MASK) != 0UL)
2759     {
2760         status = kStatus_ReadOnly;
2761     }
2762     else
2763     {
2764         /* Deinit and clear the error. */
2765         CGC_RTD->PLL1CSR = 0;
2766         status           = kStatus_Success;
2767     }
2768 
2769     return status;
2770 }
2771 
2772 /*!
2773  * @brief Set the asynchronous clock divider.
2774  *
2775  * @param asyncClk Which asynchronous clock to configure.
2776  * @param divider The divider value to set. Disabled when divider == 0.
2777  *
2778  * @note There might be glitch when changing the asynchronous divider, so make sure
2779  * the asynchronous clock is not used while changing divider.
2780  */
CLOCK_SetPll1AsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)2781 void CLOCK_SetPll1AsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
2782 {
2783     uint32_t reg;
2784 
2785     switch (asyncClk)
2786     {
2787         case kCGC_AsyncVcoClk:
2788             reg = CGC_RTD->PLL1DIV_VCO;
2789             reg =
2790                 (reg & ~(CGC_PLL1DIV_VCO_DIV1_MASK | CGC_PLL1DIV_VCO_DIV1HALT_MASK)) |
2791                 (divider > 0U ? CGC_PLL1DIV_VCO_DIV1((uint32_t)divider - 1U) : (uint32_t)CGC_PLL1DIV_VCO_DIV1HALT_MASK);
2792             CGC_RTD->PLL1DIV_VCO = reg;
2793             break;
2794         case kCGC_AsyncPfd1Div1Clk:
2795             reg = CGC_RTD->PLL1DIV_PFD_0;
2796             reg = (reg & ~(CGC_PLL1DIV_PFD_0_DIV1_MASK | CGC_PLL1DIV_PFD_0_DIV1HALT_MASK)) |
2797                   (divider > 0U ? CGC_PLL1DIV_PFD_0_DIV1((uint32_t)divider - 1U) :
2798                                   (uint32_t)CGC_PLL1DIV_PFD_0_DIV1HALT_MASK);
2799             CGC_RTD->PLL1DIV_PFD_0 = reg;
2800             break;
2801         case kCGC_AsyncPfd2Div1Clk:
2802             reg = CGC_RTD->PLL1DIV_PFD_0;
2803             reg = (reg & ~(CGC_PLL1DIV_PFD_0_DIV2_MASK | CGC_PLL1DIV_PFD_0_DIV2HALT_MASK)) |
2804                   (divider > 0U ? CGC_PLL1DIV_PFD_0_DIV2((uint32_t)divider - 1U) :
2805                                   (uint32_t)CGC_PLL1DIV_PFD_0_DIV2HALT_MASK);
2806             CGC_RTD->PLL1DIV_PFD_0 = reg;
2807             break;
2808         default:
2809             assert(false);
2810             break;
2811     }
2812 }
2813 
CLOCK_GetPll1CommonFreq(void)2814 static uint32_t CLOCK_GetPll1CommonFreq(void)
2815 {
2816     uint32_t freq = 0U;
2817     uint64_t freqTmp;
2818     uint64_t pllnumTmp;
2819 
2820     if ((CGC_RTD->PLL1CFG & CGC_PLL1CFG_SOURCE_MASK) != 0UL) /* If use FRO24M */
2821     {
2822         freq = CLOCK_GetFroFreq() / 8U;
2823     }
2824     else /* Use System OSC. */
2825     {
2826         freq = CLOCK_GetSysOscFreq();
2827     }
2828 
2829     if (freq != 0UL) /* If source is valid. */
2830     {
2831         pllnumTmp = (uint64_t)CGC_PLL1NUM_NUM_VAL;
2832         freqTmp   = (uint64_t)freq * pllnumTmp / CGC_PLL1DENOM_DENOM_VAL;
2833         freq      = freq * CGC_PLL1CFG_MULT_VAL + (uint32_t)freqTmp;
2834     }
2835 
2836     return freq;
2837 }
2838 
2839 /*!
2840  * brief Gets CGC PLL1 clock frequency.
2841  *
2842  * return  Clock frequency; If the clock is invalid, returns 0.
2843  */
CLOCK_GetPll1Freq(void)2844 uint32_t CLOCK_GetPll1Freq(void)
2845 {
2846     uint32_t freq;
2847 
2848     if ((CGC_RTD->PLL1CSR & CGC_PLL1CSR_PLLVLD_MASK) != 0UL) /* PLL1 is valid. */
2849     {
2850         freq = CLOCK_GetPll1CommonFreq();
2851     }
2852     else
2853     {
2854         freq = 0U;
2855     }
2856 
2857     return freq;
2858 }
2859 
2860 /*!
2861  * brief Gets the CGC asynchronous clock frequency from PLL1.
2862  *
2863  * param type     The asynchronous clock type.
2864  * return  Clock frequency; If the clock is invalid, returns 0.
2865  */
CLOCK_GetPll1AsyncFreq(cgc_async_clk_t type)2866 uint32_t CLOCK_GetPll1AsyncFreq(cgc_async_clk_t type)
2867 {
2868     uint32_t pllFreq;
2869     uint32_t divider;
2870     uint32_t freq;
2871 
2872     switch (type)
2873     {
2874         case kCGC_AsyncVcoClk: /* PLL1 VCO. */
2875             pllFreq = CLOCK_GetPll1Freq();
2876             divider = CGC_PLL1DIV_VCO_DIV1_VAL;
2877             break;
2878         case kCGC_AsyncPfd1Div1Clk: /* PLL1 PFD1 DIV. */
2879             pllFreq = CLOCK_GetPll1PfdFreq(kCGC_PllPfd1Clk);
2880             divider = CGC_PLL1DIV_PFD1_DIV_VAL;
2881             break;
2882         case kCGC_AsyncPfd2Div1Clk: /* PLL1 PFD2 DIV. */
2883             pllFreq = CLOCK_GetPll1PfdFreq(kCGC_PllPfd2Clk);
2884             divider = CGC_PLL1DIV_PFD2_DIV_VAL;
2885             break;
2886         default:
2887             divider = 0U;
2888             assert(false);
2889             break;
2890     }
2891 
2892     if (divider != 0UL)
2893     {
2894         freq = pllFreq / divider;
2895     }
2896     else /* Output disabled. */
2897     {
2898         freq = 0U;
2899     }
2900 
2901     return freq;
2902 }
2903 
2904 /*!
2905  * brief Gets the CGC PLL1 PFD clock frequency.
2906  *
2907  * param pfdClkout     The selected PFD clocks out. See "cgc_pll_pfd_clkout_t".
2908  * return  Clock frequency; If the clock is invalid, returns 0.
2909  */
CLOCK_GetPll1PfdFreq(cgc_pll_pfd_clkout_t pfdClkout)2910 uint32_t CLOCK_GetPll1PfdFreq(cgc_pll_pfd_clkout_t pfdClkout)
2911 {
2912     uint32_t freq      = 0U;
2913     uint32_t fracValue = 0U;
2914 
2915     if ((CGC_RTD->PLL1PFDCFG & CGC_PLLPFD_PFD_VALID_MASK(pfdClkout)) != 0UL) /* PLL1 PFD is valid. */
2916     {
2917         if (0UL == (CGC_RTD->PLL1PFDCFG & CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout)))
2918         {
2919             fracValue = (CGC_RTD->PLL1PFDCFG & CGC_PLLPFD_PFD_MASK(pfdClkout)) >> (uint32_t)pfdClkout;
2920 
2921             if (fracValue != 0UL)
2922             {
2923                 freq = CLOCK_GetPll1CommonFreq();
2924                 freq = (uint32_t)((uint64_t)freq * PFD_FREQ_CALCUL_CONSTANT /
2925                                   fracValue); /* PFD Clock Frequency = PLL output frequency * 18 / frac value. */
2926             }
2927             else
2928             {
2929             }
2930         }
2931         else
2932         {
2933         }
2934     }
2935     else
2936     {
2937     }
2938 
2939     return freq;
2940 }
2941 
2942 /*!
2943  * @brief Enables the CGC PLL1 Fractional Divide (PFD) clock out with configurations.
2944  *
2945  * PLL1 Frequency = Fref * (MULT + NUM/DENOM)
2946  * PFD Clock Frequency = PLL output frequency * 18/frac value
2947  *
2948  * Example code for configuring PLL1 as PLL1 PFD clock output:
2949  * @code
2950  * const cgc_pll1_config_t g_cgcPll1Config = {.enableMode = kCGC_PllEnable,
2951  *                                            .div1 = 0U,
2952  *                                            .pfd1Div = 0U,
2953  *                                            .pfd2Div = 0U,
2954  *                                            .src = kCGC_PllSrcFro24M,
2955  *                                            .mult = kCGC_Pll1Mult22,
2956  *                                            .num = 578,
2957  *                                            .denom = 1000};
2958  * CLOCK_InitPll1(&g_cgcPll1Config);
2959  * CLOCK_EnablePll1PfdClkout(kCGC_PllPfd0Clk, 15U);
2960  * @endcode
2961  *
2962  * @param pfdClkout  PLL1 PFD clock out select.
2963  * @param fracValue  Fractional Divider value. Recommended to be kept between 12-35 for all PFDs.
2964  */
CLOCK_EnablePll1PfdClkout(cgc_pll_pfd_clkout_t pfdClkout,uint8_t fracValue)2965 void CLOCK_EnablePll1PfdClkout(cgc_pll_pfd_clkout_t pfdClkout, uint8_t fracValue)
2966 {
2967     /*
2968      * Input fractional divider value should have a maximum size of 6 bits (64U).
2969      * Note: It is recommended that PFD settings are kept between 12-35 for all PFDs.
2970      */
2971     assert(fracValue);
2972     assert(fracValue < CGC_PLLPFD_PFD_MAX_VAL);
2973 
2974     /* Step 1. Gate PFD clock. */
2975     CGC_RTD->PLL1PFDCFG |= CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout);
2976 
2977     /* Step 2. Program the new PFD value. */
2978     CGC_RTD->PLL1PFDCFG =
2979         (CGC_RTD->PLL1PFDCFG & ~CGC_PLLPFD_PFD_MASK(pfdClkout)) | CGC_PLLPFD_PFD_VAL(pfdClkout, fracValue);
2980 
2981     /* Step 3. Ungate PFD clock. */
2982     CGC_RTD->PLL1PFDCFG &= ~CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout);
2983 
2984     /* Step 4. Wait for PFD clock to be stable. */
2985     while (0UL == (CGC_RTD->PLL1PFDCFG & CGC_PLLPFD_PFD_VALID_MASK(pfdClkout)))
2986     {
2987     }
2988 }
2989 
CLOCK_GetPll3CommonFreq(void)2990 static uint32_t CLOCK_GetPll3CommonFreq(void)
2991 {
2992     uint32_t freq = 0U;
2993     uint64_t freqTmp;
2994     uint64_t pllnumTmp;
2995 
2996     if ((CGC_AD->PLL3CFG & CGC_AD_PLL3CFG_SOURCE_MASK) != 0UL) /* If use FRO24M */
2997     {
2998         freq = CLOCK_GetFroFreq() / 8U;
2999     }
3000     else /* Use System OSC. */
3001     {
3002         freq = CLOCK_GetSysOscFreq();
3003     }
3004 
3005     if (freq != 0UL) /* If source is valid. */
3006     {
3007         pllnumTmp = (uint64_t)CGC_AD_PLL3NUM_NUM_VAL;
3008         freqTmp   = (uint64_t)freq * pllnumTmp / CGC_AD_PLL3DENOM_DENOM_VAL;
3009         freq      = freq * CGC_AD_PLL3CFG_MULT_VAL + (uint32_t)freqTmp;
3010     }
3011 
3012     return freq;
3013 }
3014 
3015 /*!
3016  * brief Gets CGC PLL3 clock frequency.
3017  *
3018  * return  Clock frequency; If the clock is invalid, returns 0.
3019  */
CLOCK_GetPll3Freq(void)3020 uint32_t CLOCK_GetPll3Freq(void)
3021 {
3022     uint32_t freq;
3023 
3024     if ((CGC_AD->PLL3CSR & CGC_AD_PLL3CSR_PLLVLD_MASK) != 0UL) /* PLL3 is valid. */
3025     {
3026         freq = CLOCK_GetPll3CommonFreq();
3027     }
3028     else
3029     {
3030         freq = 0U;
3031     }
3032 
3033     return freq;
3034 }
3035 
3036 /*!
3037  * brief Gets the CGC asynchronous clock frequency from PLL3.
3038  *
3039  * param type     The asynchronous clock type.
3040  * return  Clock frequency; If the clock is invalid, returns 0.
3041  */
CLOCK_GetPll3AsyncFreq(cgc_async_clk_t type)3042 uint32_t CLOCK_GetPll3AsyncFreq(cgc_async_clk_t type)
3043 {
3044     uint32_t pllFreq;
3045     uint32_t divider;
3046     uint32_t freq;
3047 
3048     switch (type)
3049     {
3050         case kCGC_AsyncVcoClk: /* PLL3 VCO. */
3051             pllFreq = CLOCK_GetPll3Freq();
3052             divider = CGC_AD_PLL3DIV_VCO_DIV1_VAL;
3053             break;
3054         case kCGC_AsyncPfd0Div1Clk: /* PLL3 PFD0 DIV1. */
3055             pllFreq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd0Clk);
3056             divider = CGC_AD_PLL3DIV_PFD0_DIV1_VAL;
3057             break;
3058         case kCGC_AsyncPfd0Div2Clk: /* PLL3 PFD0 DIV2. */
3059             pllFreq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd0Clk);
3060             divider = CGC_AD_PLL3DIV_PFD0_DIV2_VAL;
3061             break;
3062         case kCGC_AsyncPfd1Div1Clk: /* PLL3 PFD1 DIV1. */
3063             pllFreq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd1Clk);
3064             divider = CGC_AD_PLL3DIV_PFD1_DIV1_VAL;
3065             break;
3066         case kCGC_AsyncPfd1Div2Clk: /* PLL3 PFD1 DIV2. */
3067             pllFreq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd1Clk);
3068             divider = CGC_AD_PLL3DIV_PFD1_DIV2_VAL;
3069             break;
3070         case kCGC_AsyncPfd2Div1Clk: /* PLL3 PFD2 DIV1. */
3071             pllFreq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd2Clk);
3072             divider = CGC_AD_PLL3DIV_PFD2_DIV1_VAL;
3073             break;
3074         case kCGC_AsyncPfd2Div2Clk: /* PLL3 PFD2 DIV2. */
3075             pllFreq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd2Clk);
3076             divider = CGC_AD_PLL3DIV_PFD2_DIV2_VAL;
3077             break;
3078         case kCGC_AsyncPfd3Div1Clk: /* PLL3 PFD3 DIV1. */
3079             pllFreq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd3Clk);
3080             divider = CGC_AD_PLL3DIV_PFD3_DIV1_VAL;
3081             break;
3082         case kCGC_AsyncPfd3Div2Clk: /* PLL3 PFD3 DIV2. */
3083             pllFreq = CLOCK_GetPll3PfdFreq(kCGC_PllPfd3Clk);
3084             divider = CGC_AD_PLL3DIV_PFD3_DIV2_VAL;
3085             break;
3086         default:
3087             divider = 0U;
3088             assert(false);
3089             break;
3090     }
3091 
3092     if (divider != 0UL)
3093     {
3094         freq = pllFreq / divider;
3095     }
3096     else /* Output disabled. */
3097     {
3098         freq = 0U;
3099     }
3100 
3101     return freq;
3102 }
3103 
3104 /*!
3105  * brief Gets the CGC PLL3 PFD clock frequency.
3106  *
3107  * param pfdClkout     The selected PFD clocks out. See "cgc_pll_pfd_clkout_t".
3108  * return  Clock frequency; If the clock is invalid, returns 0.
3109  */
CLOCK_GetPll3PfdFreq(cgc_pll_pfd_clkout_t pfdClkout)3110 uint32_t CLOCK_GetPll3PfdFreq(cgc_pll_pfd_clkout_t pfdClkout)
3111 {
3112     uint32_t freq      = 0U;
3113     uint32_t fracValue = 0U;
3114 
3115     if ((CGC_AD->PLL3PFDCFG & CGC_PLLPFD_PFD_VALID_MASK(pfdClkout)) != 0UL) /* PLL3 PFD is valid. */
3116     {
3117         if (0UL == (CGC_AD->PLL3PFDCFG & CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout)))
3118         {
3119             fracValue = (CGC_AD->PLL3PFDCFG & CGC_PLLPFD_PFD_MASK(pfdClkout)) >> (uint32_t)pfdClkout;
3120 
3121             if (fracValue != 0UL)
3122             {
3123                 freq = CLOCK_GetPll3CommonFreq();
3124                 freq = (uint32_t)((uint64_t)freq * PFD_FREQ_CALCUL_CONSTANT /
3125                                   fracValue); /* PFD Clock Frequency = PLL output frequency * 18 / frac value. */
3126             }
3127             else
3128             {
3129             }
3130         }
3131         else
3132         {
3133         }
3134     }
3135     else
3136     {
3137     }
3138 
3139     return freq;
3140 }
3141 
3142 /*!
3143  * @brief Initializes the CGC PLL4.
3144  *
3145  * This function enables the CGC PLL4 clock according to the
3146  * configuration. The PLL4 can use the system OSC or FRO as
3147  * the clock source. Ensure that the source clock is valid before
3148  * calling this function.
3149  *
3150  * Example code for initializing PLL4 clock output:
3151  * @code
3152  * const cgc_pll4_config_t g_cgcPll4Config = {.enableMode = kCGC_PllEnable,
3153  *                                            .div1 = 0U,
3154  *                                            .pfd0Div1 = 0U,
3155  *                                            .pfd0Div2 = 0U,
3156  *                                            .pfd1Div1 = 0U,
3157  *                                            .pfd1Div2 = 0U,
3158  *                                            .pfd2Div1 = 0U,
3159  *                                            .pfd2Div2 = 0U,
3160  *                                            .pfd3Div1 = 0U,
3161  *                                            .pfd3Div2 = 0U,
3162  *                                            .src = kCGC_PllSrcFro24M,
3163  *                                            .mult = kCGC_Pll4Mult22,
3164  *                                            .num = 578,
3165  *                                            .denom = 1000};
3166  * CLOCK_InitPll4(&g_cgcPll4Config);
3167  * @endcode
3168  *
3169  * @param config   Pointer to the configuration structure.
3170  * @retval kStatus_Success PLL4 is initialized.
3171  * @retval kStatus_CGC_Busy PLL4 has been enabled and is used by the system clock.
3172  * @retval kStatus_ReadOnly PLL4 control register is locked.
3173  *
3174  * @note This function can't detect whether the PLL4 has been enabled and
3175  * is used by an IP.
3176  */
CLOCK_InitPll4(const cgc_pll4_config_t * config)3177 status_t CLOCK_InitPll4(const cgc_pll4_config_t *config)
3178 {
3179     status_t status;
3180 
3181     assert(config);
3182 
3183     /* De-init the PLL4 first. */
3184     status = CLOCK_DeinitPll4();
3185     if (kStatus_Success != status)
3186     {
3187         return status;
3188     }
3189 
3190     /* Now start to set up PLL clock. */
3191     /* Step 1. Setup dividers. */
3192     CGC_LPAV->PLL4DIV_VCO   = (config->div1 > 0U ? CGC_LPAV_PLL4DIV_VCO_DIV1((uint32_t)config->div1 - 1U) :
3193                                                  (uint32_t)CGC_LPAV_PLL4DIV_VCO_DIV1HALT_MASK);
3194     CGC_LPAV->PLL4DIV_PFD_0 = (config->pfd0Div1 > 0U ? CGC_LPAV_PLL4DIV_PFD_0_DIV1((uint32_t)config->pfd0Div1 - 1U) :
3195                                                        (uint32_t)CGC_LPAV_PLL4DIV_PFD_0_DIV1HALT_MASK) |
3196                               (config->pfd0Div2 > 0U ? CGC_LPAV_PLL4DIV_PFD_0_DIV2((uint32_t)config->pfd0Div2 - 1U) :
3197                                                        (uint32_t)CGC_LPAV_PLL4DIV_PFD_0_DIV2HALT_MASK) |
3198                               (config->pfd1Div1 > 0U ? CGC_LPAV_PLL4DIV_PFD_0_DIV3((uint32_t)config->pfd1Div1 - 1U) :
3199                                                        (uint32_t)CGC_LPAV_PLL4DIV_PFD_0_DIV3HALT_MASK) |
3200                               (config->pfd1Div2 > 0U ? CGC_LPAV_PLL4DIV_PFD_0_DIV4((uint32_t)config->pfd1Div2 - 1U) :
3201                                                        (uint32_t)CGC_LPAV_PLL4DIV_PFD_0_DIV4HALT_MASK);
3202     CGC_LPAV->PLL4DIV_PFD_1 = (config->pfd2Div1 > 0U ? CGC_LPAV_PLL4DIV_PFD_1_DIV1((uint32_t)config->pfd2Div1 - 1U) :
3203                                                        (uint32_t)CGC_LPAV_PLL4DIV_PFD_1_DIV1HALT_MASK) |
3204                               (config->pfd2Div2 > 0U ? CGC_LPAV_PLL4DIV_PFD_1_DIV2((uint32_t)config->pfd2Div2 - 1U) :
3205                                                        (uint32_t)CGC_LPAV_PLL4DIV_PFD_1_DIV2HALT_MASK) |
3206                               (config->pfd3Div1 > 0U ? CGC_LPAV_PLL4DIV_PFD_1_DIV3((uint32_t)config->pfd3Div1 - 1U) :
3207                                                        (uint32_t)CGC_LPAV_PLL4DIV_PFD_1_DIV3HALT_MASK) |
3208                               (config->pfd3Div2 > 0U ? CGC_LPAV_PLL4DIV_PFD_1_DIV4((uint32_t)config->pfd3Div2 - 1U) :
3209                                                        (uint32_t)CGC_LPAV_PLL4DIV_PFD_1_DIV4HALT_MASK);
3210 
3211     /* Step 2. Set PLL configuration. */
3212     CGC_LPAV->PLL4CFG = CGC_LPAV_PLL4CFG_SOURCE(config->src) | CGC_LPAV_PLL4CFG_MULT(config->mult);
3213 
3214     /* Step 3. Set Numerator and Denominator. */
3215     CGC_LPAV->PLL4DENOM = config->denom;
3216     CGC_LPAV->PLL4NUM   = config->num;
3217 
3218     /* Step 4. Enable clock. */
3219     CGC_LPAV->PLL4CSR = (uint32_t)CGC_LPAV_PLL4CSR_PLLEN_MASK | config->enableMode;
3220 
3221     /* Step 5. Wait for PLL clock to be valid. */
3222     while (0UL == (CGC_LPAV->PLL4CSR & CGC_LPAV_PLL4CSR_PLLVLD_MASK))
3223     {
3224     }
3225 
3226     return kStatus_Success;
3227 }
3228 
3229 /*!
3230  * @brief De-initializes the CGC PLL4.
3231  *
3232  * This function disables the CGC PLL4.
3233  *
3234  * @retval kStatus_Success PLL4 is deinitialized.
3235  * @retval kStatus_CGC_Busy PLL4 is used by the system clock.
3236  * @retval kStatus_ReadOnly PLL4 control register is locked.
3237  *
3238  * @note This function can't detect whether the PLL4 is used by an IP.
3239  */
CLOCK_DeinitPll4(void)3240 status_t CLOCK_DeinitPll4(void)
3241 {
3242     uint32_t reg = CGC_LPAV->PLL4CSR;
3243     status_t status;
3244 
3245     /* If clock is used by system, return error. */
3246     if ((reg & CGC_LPAV_PLL4CSR_PLLSEL_MASK) != 0UL)
3247     {
3248         status = kStatus_CGC_Busy;
3249     }
3250     /* If configure register is locked, return error. */
3251     else if ((reg & CGC_LPAV_PLL4CSR_LK_MASK) != 0UL)
3252     {
3253         status = kStatus_ReadOnly;
3254     }
3255     else
3256     {
3257         /* Deinit and clear the error. */
3258         CGC_LPAV->PLL4CSR = 0;
3259         status            = kStatus_Success;
3260     }
3261 
3262     return status;
3263 }
3264 
3265 /*!
3266  * @brief Set the asynchronous clock divider.
3267  *
3268  * @param asyncClk Which asynchronous clock to configure.
3269  * @param divider The divider value to set. Disabled when divider == 0.
3270  *
3271  * @note There might be glitch when changing the asynchronous divider, so make sure
3272  * the asynchronous clock is not used while changing divider.
3273  */
CLOCK_SetPll4AsyncClkDiv(cgc_async_clk_t asyncClk,uint8_t divider)3274 void CLOCK_SetPll4AsyncClkDiv(cgc_async_clk_t asyncClk, uint8_t divider)
3275 {
3276     uint32_t reg;
3277 
3278     switch (asyncClk)
3279     {
3280         case kCGC_AsyncVcoClk:
3281             reg = CGC_LPAV->PLL4DIV_VCO;
3282             reg =
3283                 (reg & ~(CGC_LPAV_PLL4DIV_VCO_DIV1_MASK | CGC_LPAV_PLL4DIV_VCO_DIV1HALT_MASK)) |
3284                 (divider > 0U ? CGC_LPAV_PLL4DIV_VCO_DIV1((uint32_t)divider - 1U) : CGC_LPAV_PLL4DIV_VCO_DIV1HALT_MASK);
3285             CGC_LPAV->PLL4DIV_VCO = reg;
3286             break;
3287         case kCGC_AsyncPfd0Div1Clk:
3288             reg = CGC_LPAV->PLL4DIV_PFD_0;
3289             reg = (reg & ~(CGC_LPAV_PLL4DIV_PFD_0_DIV1_MASK | CGC_LPAV_PLL4DIV_PFD_0_DIV1HALT_MASK)) |
3290                   (divider > 0U ? CGC_LPAV_PLL4DIV_PFD_0_DIV1((uint32_t)divider - 1U) :
3291                                   CGC_LPAV_PLL4DIV_PFD_0_DIV1HALT_MASK);
3292             CGC_LPAV->PLL4DIV_PFD_0 = reg;
3293             break;
3294         case kCGC_AsyncPfd0Div2Clk:
3295             reg = CGC_LPAV->PLL4DIV_PFD_0;
3296             reg = (reg & ~(CGC_LPAV_PLL4DIV_PFD_0_DIV2_MASK | CGC_LPAV_PLL4DIV_PFD_0_DIV2HALT_MASK)) |
3297                   (divider > 0U ? CGC_LPAV_PLL4DIV_PFD_0_DIV2((uint32_t)divider - 1U) :
3298                                   CGC_LPAV_PLL4DIV_PFD_0_DIV2HALT_MASK);
3299             CGC_LPAV->PLL4DIV_PFD_0 = reg;
3300             break;
3301         case kCGC_AsyncPfd1Div1Clk:
3302             reg = CGC_LPAV->PLL4DIV_PFD_0;
3303             reg = (reg & ~(CGC_LPAV_PLL4DIV_PFD_0_DIV3_MASK | CGC_LPAV_PLL4DIV_PFD_0_DIV3HALT_MASK)) |
3304                   (divider > 0U ? CGC_LPAV_PLL4DIV_PFD_0_DIV3((uint32_t)divider - 1U) :
3305                                   CGC_LPAV_PLL4DIV_PFD_0_DIV3HALT_MASK);
3306             CGC_LPAV->PLL4DIV_PFD_0 = reg;
3307             break;
3308         case kCGC_AsyncPfd1Div2Clk:
3309             reg = CGC_LPAV->PLL4DIV_PFD_0;
3310             reg = (reg & ~(CGC_LPAV_PLL4DIV_PFD_0_DIV4_MASK | CGC_LPAV_PLL4DIV_PFD_0_DIV4HALT_MASK)) |
3311                   (divider > 0U ? CGC_LPAV_PLL4DIV_PFD_0_DIV4((uint32_t)divider - 1U) :
3312                                   CGC_LPAV_PLL4DIV_PFD_0_DIV4HALT_MASK);
3313             CGC_LPAV->PLL4DIV_PFD_0 = reg;
3314             break;
3315         case kCGC_AsyncPfd2Div1Clk:
3316             reg = CGC_LPAV->PLL4DIV_PFD_1;
3317             reg = (reg & ~(CGC_LPAV_PLL4DIV_PFD_1_DIV1_MASK | CGC_LPAV_PLL4DIV_PFD_1_DIV1HALT_MASK)) |
3318                   (divider > 0U ? CGC_LPAV_PLL4DIV_PFD_1_DIV1((uint32_t)divider - 1U) :
3319                                   CGC_LPAV_PLL4DIV_PFD_1_DIV1HALT_MASK);
3320             CGC_LPAV->PLL4DIV_PFD_1 = reg;
3321             break;
3322         case kCGC_AsyncPfd2Div2Clk:
3323             reg = CGC_LPAV->PLL4DIV_PFD_1;
3324             reg = (reg & ~(CGC_LPAV_PLL4DIV_PFD_1_DIV2_MASK | CGC_LPAV_PLL4DIV_PFD_1_DIV2HALT_MASK)) |
3325                   (divider > 0U ? CGC_LPAV_PLL4DIV_PFD_1_DIV2((uint32_t)divider - 1U) :
3326                                   CGC_LPAV_PLL4DIV_PFD_1_DIV2HALT_MASK);
3327             CGC_LPAV->PLL4DIV_PFD_1 = reg;
3328             break;
3329         case kCGC_AsyncPfd3Div1Clk:
3330             reg = CGC_LPAV->PLL4DIV_PFD_1;
3331             reg = (reg & ~(CGC_LPAV_PLL4DIV_PFD_1_DIV3_MASK | CGC_LPAV_PLL4DIV_PFD_1_DIV3HALT_MASK)) |
3332                   (divider > 0U ? CGC_LPAV_PLL4DIV_PFD_1_DIV3((uint32_t)divider - 1U) :
3333                                   CGC_LPAV_PLL4DIV_PFD_1_DIV3HALT_MASK);
3334             CGC_LPAV->PLL4DIV_PFD_1 = reg;
3335             break;
3336         case kCGC_AsyncPfd3Div2Clk:
3337             reg = CGC_LPAV->PLL4DIV_PFD_1;
3338             reg = (reg & ~(CGC_LPAV_PLL4DIV_PFD_1_DIV4_MASK | CGC_LPAV_PLL4DIV_PFD_1_DIV4HALT_MASK)) |
3339                   (divider > 0U ? CGC_LPAV_PLL4DIV_PFD_1_DIV4((uint32_t)divider - 1U) :
3340                                   CGC_LPAV_PLL4DIV_PFD_1_DIV4HALT_MASK);
3341             CGC_LPAV->PLL4DIV_PFD_1 = reg;
3342             break;
3343         default:
3344             assert(false);
3345             break;
3346     }
3347 }
3348 
CLOCK_GetPll4CommonFreq(void)3349 static uint32_t CLOCK_GetPll4CommonFreq(void)
3350 {
3351     uint32_t freq = 0U;
3352     uint64_t freqTmp;
3353     uint64_t pllnumTmp;
3354 
3355     if ((CGC_LPAV->PLL4CFG & CGC_LPAV_PLL4CFG_SOURCE_MASK) != 0UL) /* If use FRO24M */
3356     {
3357         freq = CLOCK_GetFroFreq() / 8U;
3358     }
3359     else /* Use System OSC. */
3360     {
3361         freq = CLOCK_GetSysOscFreq();
3362     }
3363 
3364     if (freq != 0UL) /* If source is valid. */
3365     {
3366         pllnumTmp = (uint64_t)CGC_LPAV_PLL4NUM_NUM_VAL;
3367         freqTmp   = (uint64_t)freq * pllnumTmp / CGC_LPAV_PLL4DENOM_DENOM_VAL;
3368         freq      = freq * CGC_LPAV_PLL4CFG_MULT_VAL + (uint32_t)freqTmp;
3369     }
3370 
3371     return freq;
3372 }
3373 
3374 /*!
3375  * brief Gets CGC PLL4 clock frequency.
3376  *
3377  * return  Clock frequency; If the clock is invalid, returns 0.
3378  */
CLOCK_GetPll4Freq(void)3379 uint32_t CLOCK_GetPll4Freq(void)
3380 {
3381     uint32_t freq;
3382 
3383     if ((CGC_LPAV->PLL4CSR & CGC_LPAV_PLL4CSR_PLLVLD_MASK) != 0UL) /* PLL4 is valid. */
3384     {
3385         freq = CLOCK_GetPll4CommonFreq();
3386     }
3387     else
3388     {
3389         freq = 0U;
3390     }
3391 
3392     return freq;
3393 }
3394 
3395 /*!
3396  * brief Gets the CGC asynchronous clock frequency from PLL4.
3397  *
3398  * param type     The asynchronous clock type.
3399  * return  Clock frequency; If the clock is invalid, returns 0.
3400  */
CLOCK_GetPll4AsyncFreq(cgc_async_clk_t type)3401 uint32_t CLOCK_GetPll4AsyncFreq(cgc_async_clk_t type)
3402 {
3403     uint32_t pllFreq;
3404     uint32_t divider;
3405     uint32_t freq;
3406 
3407     switch (type)
3408     {
3409         case kCGC_AsyncVcoClk: /* PLL4 VCO. */
3410             pllFreq = CLOCK_GetPll4Freq();
3411             divider = CGC_LPAV_PLL4DIV_VCO_DIV1_VAL;
3412             break;
3413         case kCGC_AsyncPfd0Div1Clk: /* PLL4 PFD0 DIV1. */
3414             pllFreq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd0Clk);
3415             divider = CGC_LPAV_PLL4DIV_PFD0_DIV1_VAL;
3416             break;
3417         case kCGC_AsyncPfd0Div2Clk: /* PLL4 PFD0 DIV2. */
3418             pllFreq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd0Clk);
3419             divider = CGC_LPAV_PLL4DIV_PFD0_DIV2_VAL;
3420             break;
3421         case kCGC_AsyncPfd1Div1Clk: /* PLL4 PFD1 DIV1. */
3422             pllFreq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd1Clk);
3423             divider = CGC_LPAV_PLL4DIV_PFD1_DIV1_VAL;
3424             break;
3425         case kCGC_AsyncPfd1Div2Clk: /* PLL4 PFD1 DIV2. */
3426             pllFreq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd1Clk);
3427             divider = CGC_LPAV_PLL4DIV_PFD1_DIV2_VAL;
3428             break;
3429         case kCGC_AsyncPfd2Div1Clk: /* PLL4 PFD2 DIV1. */
3430             pllFreq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd2Clk);
3431             divider = CGC_LPAV_PLL4DIV_PFD2_DIV1_VAL;
3432             break;
3433         case kCGC_AsyncPfd2Div2Clk: /* PLL4 PFD2 DIV2. */
3434             pllFreq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd2Clk);
3435             divider = CGC_LPAV_PLL4DIV_PFD2_DIV2_VAL;
3436             break;
3437         case kCGC_AsyncPfd3Div1Clk: /* PLL4 PFD3 DIV1. */
3438             pllFreq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd3Clk);
3439             divider = CGC_LPAV_PLL4DIV_PFD3_DIV1_VAL;
3440             break;
3441         case kCGC_AsyncPfd3Div2Clk: /* PLL4 PFD3 DIV2. */
3442             pllFreq = CLOCK_GetPll4PfdFreq(kCGC_PllPfd3Clk);
3443             divider = CGC_LPAV_PLL4DIV_PFD3_DIV2_VAL;
3444             break;
3445         default:
3446             divider = 0U;
3447             assert(false);
3448             break;
3449     }
3450 
3451     if (divider != 0UL)
3452     {
3453         freq = pllFreq / divider;
3454     }
3455     else /* Output disabled. */
3456     {
3457         freq = 0U;
3458     }
3459 
3460     return freq;
3461 }
3462 
3463 /*!
3464  * brief Gets the CGC PLL4 PFD clock frequency.
3465  *
3466  * param pfdClkout     The selected PFD clocks out. See "cgc_pll_pfd_clkout_t".
3467  * return  Clock frequency; If the clock is invalid, returns 0.
3468  */
CLOCK_GetPll4PfdFreq(cgc_pll_pfd_clkout_t pfdClkout)3469 uint32_t CLOCK_GetPll4PfdFreq(cgc_pll_pfd_clkout_t pfdClkout)
3470 {
3471     uint32_t freq      = 0U;
3472     uint32_t fracValue = 0U;
3473 
3474     if ((CGC_LPAV->PLL4PFDCFG & CGC_PLLPFD_PFD_VALID_MASK(pfdClkout)) != 0UL) /* PLL4 PFD is valid. */
3475     {
3476         if (0UL == (CGC_LPAV->PLL4PFDCFG & CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout)))
3477         {
3478             fracValue = (CGC_LPAV->PLL4PFDCFG & CGC_PLLPFD_PFD_MASK(pfdClkout)) >> (uint32_t)pfdClkout;
3479 
3480             if (fracValue != 0UL)
3481             {
3482                 freq = CLOCK_GetPll4CommonFreq();
3483                 freq = (uint32_t)((uint64_t)freq * PFD_FREQ_CALCUL_CONSTANT /
3484                                   fracValue); /* PFD Clock Frequency = PLL output frequency * 18 / frac value. */
3485             }
3486             else
3487             {
3488             }
3489         }
3490         else
3491         {
3492         }
3493     }
3494     else
3495     {
3496     }
3497 
3498     return freq;
3499 }
3500 
3501 /*!
3502  * @brief Enables the CGC PLL4 Fractional Divide (PFD) clock out with configurations.
3503  *
3504  * PLL4 Frequency = Fref * (MULT + NUM/DENOM)
3505  * PFD Clock Frequency = PLL output frequency * 18/frac value
3506  *
3507  * Example code for configuring PLL4 as PLL4 PFD clock output:
3508  * @code
3509  * const cgc_pll4_config_t g_cgcPll4Config = {.enableMode = kCGC_PllEnable,
3510  *                                            .div1 = 0U,
3511  *                                            .pfd0Div1 = 0U,
3512  *                                            .pfd0Div2 = 0U,
3513  *                                            .pfd1Div1 = 0U,
3514  *                                            .pfd1Div2 = 0U,
3515  *                                            .pfd2Div1 = 0U,
3516  *                                            .pfd2Div2 = 0U,
3517  *                                            .pfd3Div1 = 0U,
3518  *                                            .pfd3Div2 = 0U,
3519  *                                            .src = kCGC_PllSrcFro24M,
3520  *                                            .mult = kCGC_Pll4Mult22,
3521  *                                            .num = 578,
3522  *                                            .denom = 1000};
3523  * CLOCK_InitPll4(&g_cgcPll4Config);
3524  * CLOCK_EnablePll4PfdClkout(kCGC_PllPfd0Clk, 15U);
3525  * @endcode
3526  *
3527  * @param pfdClkout  PLL4 PFD clock out select.
3528  * @param fracValue  Fractional Divider value. Recommended to be kept between 12-35 for all PFDs.
3529  */
CLOCK_EnablePll4PfdClkout(cgc_pll_pfd_clkout_t pfdClkout,uint8_t fracValue)3530 void CLOCK_EnablePll4PfdClkout(cgc_pll_pfd_clkout_t pfdClkout, uint8_t fracValue)
3531 {
3532     /*
3533      * Input fractional divider value should have a maximum size of 6 bits (64U).
3534      * Note: It is recommended that PFD settings are kept between 12-35 for all PFDs.
3535      */
3536     assert(fracValue);
3537     assert(fracValue < CGC_PLLPFD_PFD_MAX_VAL);
3538 
3539     /* Step 1. Gate PFD clock. */
3540     CGC_LPAV->PLL4PFDCFG |= CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout);
3541 
3542     /* Step 2. Program the new PFD value. */
3543     CGC_LPAV->PLL4PFDCFG =
3544         (CGC_LPAV->PLL4PFDCFG & ~CGC_PLLPFD_PFD_MASK(pfdClkout)) | CGC_PLLPFD_PFD_VAL(pfdClkout, fracValue);
3545 
3546     /* Step 3. Ungate PFD clock. */
3547     CGC_LPAV->PLL4PFDCFG &= ~CGC_PLLPFD_PFD_CLKGATE_MASK(pfdClkout);
3548 
3549     /* Step 4. Wait for PFD clock to be stable. */
3550     while (0UL == (CGC_LPAV->PLL4PFDCFG & CGC_PLLPFD_PFD_VALID_MASK(pfdClkout)))
3551     {
3552     }
3553 }
3554 
3555 /*!
3556  * @brief Gets the WDOG clock frequency in RTD and LPAV.
3557  *
3558  * @param instance The WDOG instance (0-2, 5).
3559  * @return  Clock frequency; If the clock is invalid, returns 0.
3560  */
CLOCK_GetWdogClkFreq(uint32_t instance)3561 uint32_t CLOCK_GetWdogClkFreq(uint32_t instance)
3562 {
3563     uint32_t freq;
3564     uint32_t reg = 0U;
3565 
3566     switch (instance)
3567     {
3568         case 0:
3569             reg  = PCC_REG(kCLOCK_Wdog0);
3570             freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3571             break;
3572         case 1:
3573             reg  = PCC_REG(kCLOCK_Wdog1);
3574             freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3575             break;
3576         case 2:
3577             reg  = PCC_REG(kCLOCK_Wdog2);
3578             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
3579             break;
3580         case 5:
3581             reg  = PCC_REG(kCLOCK_Wdog5);
3582             freq = CLOCK_GetPcc5BusFreq(PCC_PCS_VAL(reg));
3583             break;
3584         default:
3585             assert(false);
3586             freq = 0;
3587             break;
3588     }
3589 
3590     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3591 }
3592 
3593 /*!
3594  * @brief Gets the FlexSPI clock frequency in RTD.
3595  *
3596  * @param instance The FlexSPI instance (0-1).
3597  * @return  Clock frequency; If the clock is invalid, returns 0.
3598  */
CLOCK_GetFlexspiClkFreq(uint32_t instance)3599 uint32_t CLOCK_GetFlexspiClkFreq(uint32_t instance)
3600 {
3601     uint32_t freq;
3602     uint32_t reg = 0U;
3603 
3604     switch (instance)
3605     {
3606         case 0:
3607             reg  = PCC_REG(kCLOCK_Flexspi0);
3608             freq = CLOCK_GetPcc0PlatFreq(PCC_PCS_VAL(reg));
3609             break;
3610         case 1:
3611             reg  = PCC_REG(kCLOCK_Flexspi1);
3612             freq = CLOCK_GetPcc0PlatFreq(PCC_PCS_VAL(reg));
3613             break;
3614         default:
3615             assert(false);
3616             freq = 0;
3617             break;
3618     }
3619 
3620     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3621 }
3622 
3623 /*!
3624  * @brief Gets the LPIT clock frequency in RTD.
3625  *
3626  * @return  Clock frequency; If the clock is invalid, returns 0.
3627  */
CLOCK_GetLpitClkFreq(void)3628 uint32_t CLOCK_GetLpitClkFreq(void)
3629 {
3630     uint32_t freq;
3631     uint32_t reg;
3632 
3633     reg  = PCC_REG(kCLOCK_Lpit0);
3634     freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3635 
3636     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3637 }
3638 
3639 /*!
3640  * @brief Gets the FlexIO clock frequency in RTD.
3641  *
3642  * @return  Clock frequency; If the clock is invalid, returns 0.
3643  */
CLOCK_GetFlexioClkFreq(void)3644 uint32_t CLOCK_GetFlexioClkFreq(void)
3645 {
3646     uint32_t freq;
3647     uint32_t reg;
3648 
3649     reg  = PCC_REG(kCLOCK_Flexio0);
3650     freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3651 
3652     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3653 }
3654 
3655 /*!
3656  * @brief Gets the I3C clock frequency in RTD and LPAV.
3657  *
3658  * @param instance The I3C instance (0-1).
3659  * @return  Clock frequency; If the clock is invalid, returns 0.
3660  */
CLOCK_GetI3cClkFreq(uint32_t instance)3661 uint32_t CLOCK_GetI3cClkFreq(uint32_t instance)
3662 {
3663     uint32_t freq;
3664     uint32_t reg = 0U;
3665 
3666     switch (instance)
3667     {
3668         case 0:
3669             reg  = PCC_REG(kCLOCK_I3c0);
3670             freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3671             break;
3672         case 1:
3673             reg  = PCC_REG(kCLOCK_I3c1);
3674             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
3675             break;
3676         default:
3677             assert(false);
3678             freq = 0;
3679             break;
3680     }
3681 
3682     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3683 }
3684 
3685 /*!
3686  * @brief Gets the LPSPI clock frequency in RTD.
3687  *
3688  * @param instance The LPSPI instance (0-3).
3689  * @return  Clock frequency; If the clock is invalid, returns 0.
3690  */
CLOCK_GetLpspiClkFreq(uint32_t instance)3691 uint32_t CLOCK_GetLpspiClkFreq(uint32_t instance)
3692 {
3693     uint32_t freq;
3694     uint32_t reg = 0U;
3695 
3696     switch (instance)
3697     {
3698         case 0:
3699             reg  = PCC_REG(kCLOCK_Lpspi0);
3700             freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3701             break;
3702         case 1:
3703             reg  = PCC_REG(kCLOCK_Lpspi1);
3704             freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3705             break;
3706         case 2:
3707             reg  = PCC_REG(kCLOCK_Lpspi2);
3708             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
3709             break;
3710         case 3:
3711             reg  = PCC_REG(kCLOCK_Lpspi3);
3712             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
3713             break;
3714         default:
3715             assert(false);
3716             freq = 0;
3717             break;
3718     }
3719 
3720     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3721 }
3722 
3723 /*!
3724  * @brief Gets the ADC clock frequency.
3725  *
3726  * @param instance The ADC instance (0-1).
3727  * @return  Clock frequency; If the clock is invalid, returns 0.
3728  */
CLOCK_GetAdcClkFreq(uint32_t instance)3729 uint32_t CLOCK_GetAdcClkFreq(uint32_t instance)
3730 {
3731     uint32_t freq;
3732     uint32_t reg = 0U;
3733 
3734     switch (instance)
3735     {
3736         case 0:
3737             reg  = PCC_REG(kCLOCK_Adc0);
3738             freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3739             break;
3740         case 1:
3741             reg  = PCC_REG(kCLOCK_Adc1);
3742             freq = CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg));
3743             break;
3744         default:
3745             assert(false);
3746             freq = 0;
3747             break;
3748     }
3749 
3750     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3751 }
3752 
3753 /*!
3754  * @brief Gets the DAC clock frequency.
3755  *
3756  * @param instance The DAC instance (0-1).
3757  * @return  Clock frequency; If the clock is invalid, returns 0.
3758  */
CLOCK_GetDacClkFreq(uint32_t instance)3759 uint32_t CLOCK_GetDacClkFreq(uint32_t instance)
3760 {
3761     uint32_t freq;
3762     uint32_t reg = 0U;
3763 
3764     switch (instance)
3765     {
3766         case 0:
3767             reg  = PCC_REG(kCLOCK_Dac0);
3768             freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3769             break;
3770         case 1:
3771             reg  = PCC_REG(kCLOCK_Dac1);
3772             freq = CLOCK_GetPcc0BusFreq(PCC_PCS_VAL(reg));
3773             break;
3774         default:
3775             assert(false);
3776             freq = 0;
3777             break;
3778     }
3779 
3780     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3781 }
3782 
3783 /*!
3784  * @brief Gets the TPIU clock frequency.
3785  *
3786  * @return  Clock frequency; If the clock is invalid, returns 0.
3787  */
CLOCK_GetTpiuClkFreq(void)3788 uint32_t CLOCK_GetTpiuClkFreq(void)
3789 {
3790     uint32_t freq;
3791     uint32_t reg = PCC_REG(kCLOCK_Tpiu);
3792 
3793     freq = CLOCK_GetPcc0PlatFreq(PCC_PCS_VAL(reg));
3794 
3795     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3796 }
3797 
3798 /*!
3799  * @brief Gets the SWO clock frequency.
3800  *
3801  * @return  Clock frequency; If the clock is invalid, returns 0.
3802  */
CLOCK_GetSwoClkFreq(void)3803 uint32_t CLOCK_GetSwoClkFreq(void)
3804 {
3805     uint32_t freq;
3806     uint32_t reg = PCC_REG(kCLOCK_Swo);
3807 
3808     freq = CLOCK_GetPcc1PlatFreq(PCC_PCS_VAL(reg));
3809 
3810     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3811 }
3812 
CLOCK_GetTpm2ClkFreq(uint32_t pcs)3813 static uint32_t CLOCK_GetTpm2ClkFreq(uint32_t pcs)
3814 {
3815     uint32_t freq;
3816     uint32_t reg;
3817 
3818     switch (pcs)
3819     {
3820         case 0U:
3821             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd2Div1Clk);
3822             break;
3823         case 1U:
3824             freq = CLOCK_GetMclkFreq(1);
3825             break;
3826         default:
3827             reg = PCC_REG(kCLOCK_Tpm2);
3828             assert(pcs == 2U); /* Must be TPM2_PCC_ASYNC_CLK */
3829             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3830             break;
3831     }
3832 
3833     return freq;
3834 }
3835 
CLOCK_GetTpm3ClkFreq(uint32_t pcs)3836 static uint32_t CLOCK_GetTpm3ClkFreq(uint32_t pcs)
3837 {
3838     uint32_t freq;
3839     uint32_t reg;
3840 
3841     switch (pcs)
3842     {
3843         case 0U:
3844             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd2Div1Clk);
3845             break;
3846         case 1U:
3847             freq = CLOCK_GetRtdAudClkFreq();
3848             break;
3849         case 2U:
3850             freq = CLOCK_GetLpavAudClkFreq();
3851             break;
3852         default:
3853             reg = PCC_REG(kCLOCK_Tpm3);
3854             assert(pcs == 3U); /* Must be TPM3_PCC_ASYNC_CLK */
3855             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3856             break;
3857     }
3858 
3859     return freq;
3860 }
3861 
CLOCK_GetTpm67ClkFreq(clock_ip_name_t name,uint32_t pcs)3862 static uint32_t CLOCK_GetTpm67ClkFreq(clock_ip_name_t name, uint32_t pcs)
3863 {
3864     uint32_t freq;
3865     uint32_t reg;
3866 
3867     switch (pcs)
3868     {
3869         case 0U:
3870             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd1Div1Clk);
3871             break;
3872         case 1U:
3873             freq = CLOCK_GetAdAudClkFreq();
3874             break;
3875         case 2U:
3876             freq = CLOCK_GetLpavAudClkFreq();
3877             break;
3878         default:
3879             reg = PCC_REG(name);
3880             assert(pcs == 3U); /* Must be TPM67_PCC_ASYNC_CLK */
3881             freq = CLOCK_GetPcc4BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3882             break;
3883     }
3884 
3885     return freq;
3886 }
3887 
CLOCK_GetTpm8ClkFreq(uint32_t pcs)3888 static uint32_t CLOCK_GetTpm8ClkFreq(uint32_t pcs)
3889 {
3890     uint32_t freq;
3891     uint32_t reg;
3892 
3893     switch (pcs)
3894     {
3895         case 0U:
3896             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd2Div1Clk);
3897             break;
3898         case 1U:
3899             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd1Div1Clk);
3900             break;
3901         case 2U:
3902             freq = CLOCK_GetRtdAudClkFreq();
3903             break;
3904         case 3U:
3905             freq = CLOCK_GetAdAudClkFreq();
3906             break;
3907         case 4U:
3908             freq = CLOCK_GetLpavAudClkFreq();
3909             break;
3910         default:
3911             reg = PCC_REG(kCLOCK_Tpm8);
3912             assert(pcs == 5U); /* Must be TPM8_PCC_ASYNC_CLK */
3913             freq = CLOCK_GetPcc5BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3914             break;
3915     }
3916 
3917     return freq;
3918 }
3919 
3920 /*!
3921  * @brief Gets the TPM clock frequency in RTD and LPAV.
3922  *
3923  * @param instance The TPM instance (0-8).
3924  * @return  Clock frequency; If the clock is invalid, returns 0.
3925  */
CLOCK_GetTpmClkFreq(uint32_t instance)3926 uint32_t CLOCK_GetTpmClkFreq(uint32_t instance)
3927 {
3928     uint32_t freq;
3929     uint32_t pcs;
3930     uint32_t reg;
3931 
3932     switch (instance)
3933     {
3934         case 0:
3935             reg  = PCC_REG(kCLOCK_Tpm0);
3936             freq = CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3937             break;
3938         case 1:
3939             reg  = PCC_REG(kCLOCK_Tpm1);
3940             freq = CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3941             break;
3942         case 2:
3943             pcs  = (CGC_RTD->TPM3_2CLK & CGC_TPM3_2CLK_TPM2CLK_MASK) >> CGC_TPM3_2CLK_TPM2CLK_SHIFT;
3944             freq = CLOCK_GetTpm2ClkFreq(pcs);
3945             break;
3946         case 3:
3947             pcs  = (CGC_RTD->TPM3_2CLK & CGC_TPM3_2CLK_TPM3CLK_MASK) >> CGC_TPM3_2CLK_TPM3CLK_SHIFT;
3948             freq = CLOCK_GetTpm3ClkFreq(pcs);
3949             break;
3950         case 4:
3951             reg  = PCC_REG(kCLOCK_Tpm4);
3952             freq = CLOCK_GetPcc3BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3953             break;
3954         case 5:
3955             reg  = PCC_REG(kCLOCK_Tpm5);
3956             freq = CLOCK_GetPcc3BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
3957             break;
3958         case 6:
3959             pcs  = (CGC_AD->TPM6_7CLK & CGC_AD_TPM6_7CLK_TPM6CLK_MASK) >> CGC_AD_TPM6_7CLK_TPM6CLK_SHIFT;
3960             freq = CLOCK_GetTpm67ClkFreq(kCLOCK_Tpm6, pcs);
3961             break;
3962         case 7:
3963             pcs  = (CGC_AD->TPM6_7CLK & CGC_AD_TPM6_7CLK_TPM7CLK_MASK) >> CGC_AD_TPM6_7CLK_TPM7CLK_SHIFT;
3964             freq = CLOCK_GetTpm67ClkFreq(kCLOCK_Tpm7, pcs);
3965             break;
3966         case 8:
3967             pcs  = (CGC_LPAV->TPM8CLK & CGC_LPAV_TPM8CLK_TPM8CLK_MASK) >> CGC_LPAV_TPM8CLK_TPM8CLK_SHIFT;
3968             freq = CLOCK_GetTpm8ClkFreq(pcs);
3969             break;
3970         default:
3971             assert(false);
3972             freq = 0;
3973             break;
3974     }
3975 
3976     return freq;
3977 }
3978 
3979 /*!
3980  * @brief Gets the LPI2C clock frequency in RTD.
3981  *
3982  * @param instance The LPI2C instance (0-3).
3983  * @return  Clock frequency; If the clock is invalid, returns 0.
3984  */
CLOCK_GetLpi2cClkFreq(uint32_t instance)3985 uint32_t CLOCK_GetLpi2cClkFreq(uint32_t instance)
3986 {
3987     uint32_t freq;
3988     uint32_t reg = 0U;
3989 
3990     switch (instance)
3991     {
3992         case 0:
3993             reg  = PCC_REG(kCLOCK_Lpi2c0);
3994             freq = CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg));
3995             break;
3996         case 1:
3997             reg  = PCC_REG(kCLOCK_Lpi2c1);
3998             freq = CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg));
3999             break;
4000         case 2:
4001             reg  = PCC_REG(kCLOCK_Lpi2c2);
4002             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
4003             break;
4004         case 3:
4005             reg  = PCC_REG(kCLOCK_Lpi2c3);
4006             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
4007             break;
4008         default:
4009             assert(false);
4010             freq = 0;
4011             break;
4012     }
4013 
4014     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4015 }
4016 
4017 /*!
4018  * @brief Gets the LPUART clock frequency in RTD.
4019  *
4020  * @param instance The LPUART instance (0-3).
4021  * @return  Clock frequency; If the clock is invalid, returns 0.
4022  */
CLOCK_GetLpuartClkFreq(uint32_t instance)4023 uint32_t CLOCK_GetLpuartClkFreq(uint32_t instance)
4024 {
4025     uint32_t freq;
4026     uint32_t reg = 0U;
4027 
4028     switch (instance)
4029     {
4030         case 0:
4031             reg  = PCC_REG(kCLOCK_Lpuart0);
4032             freq = CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg));
4033             break;
4034         case 1:
4035             reg  = PCC_REG(kCLOCK_Lpuart1);
4036             freq = CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg));
4037             break;
4038         case 2:
4039             reg  = PCC_REG(kCLOCK_Lpuart2);
4040             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
4041             break;
4042         case 3:
4043             reg  = PCC_REG(kCLOCK_Lpuart3);
4044             freq = CLOCK_GetPcc2BusFreq(PCC_PCS_VAL(reg));
4045             break;
4046         default:
4047             assert(false);
4048             freq = 0;
4049             break;
4050     }
4051 
4052     return freq * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4053 }
4054 
4055 /*!
4056  * @brief Gets the FlexCAN clock frequency.
4057  *
4058  * @return  Clock frequency; If the clock is invalid, returns 0.
4059  */
CLOCK_GetFlexcanClkFreq(void)4060 uint32_t CLOCK_GetFlexcanClkFreq(void)
4061 {
4062     uint32_t reg = PCC_REG(kCLOCK_Flexcan);
4063     return CLOCK_GetPcc1BusFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4064 }
4065 
4066 /*!
4067  * @brief Gets the CSI clock frequency.
4068  *
4069  * @return  Clock frequency; If the clock is invalid, returns 0.
4070  */
CLOCK_GetCsiClkFreq(void)4071 uint32_t CLOCK_GetCsiClkFreq(void)
4072 {
4073     uint32_t reg = PCC_REG(kCLOCK_Csi);
4074     return CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4075 }
4076 
4077 /*!
4078  * @brief Gets the DSI clock frequency.
4079  *
4080  * @return  Clock frequency; If the clock is invalid, returns 0.
4081  */
CLOCK_GetDsiClkFreq(void)4082 uint32_t CLOCK_GetDsiClkFreq(void)
4083 {
4084     uint32_t reg = PCC_REG(kCLOCK_Dsi);
4085     return CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4086 }
4087 
4088 /*!
4089  * @brief Gets the EPDC clock frequency.
4090  *
4091  * @return  Clock frequency; If the clock is invalid, returns 0.
4092  */
CLOCK_GetEpdcClkFreq(void)4093 uint32_t CLOCK_GetEpdcClkFreq(void)
4094 {
4095     uint32_t reg = PCC_REG(kCLOCK_Epdc);
4096     return CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4097 }
4098 
4099 /*!
4100  * @brief Gets the GPU2D clock frequency.
4101  *
4102  * @return  Clock frequency; If the clock is invalid, returns 0.
4103  */
CLOCK_GetGpu2dClkFreq(void)4104 uint32_t CLOCK_GetGpu2dClkFreq(void)
4105 {
4106     uint32_t reg = PCC_REG(kCLOCK_Gpu2d);
4107     return CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4108 }
4109 
4110 /*!
4111  * @brief Gets the GPU3D clock frequency.
4112  *
4113  * @return  Clock frequency; If the clock is invalid, returns 0.
4114  */
CLOCK_GetGpu3dClkFreq(void)4115 uint32_t CLOCK_GetGpu3dClkFreq(void)
4116 {
4117     uint32_t reg = PCC_REG(kCLOCK_Gpu3d);
4118     return CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4119 }
4120 
4121 /*!
4122  * @brief Gets the DC Nano clock frequency.
4123  *
4124  * @return  Clock frequency; If the clock is invalid, returns 0.
4125  */
CLOCK_GetDcnanoClkFreq(void)4126 uint32_t CLOCK_GetDcnanoClkFreq(void)
4127 {
4128     uint32_t reg = PCC_REG(kCLOCK_Dcnano);
4129     return CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4130 }
4131 
4132 /*!
4133  * @brief Gets the CSI clk_ui clock frequency.
4134  *
4135  * @return  Clock frequency; If the clock is invalid, returns 0.
4136  */
CLOCK_GetCsiUiClkFreq(void)4137 uint32_t CLOCK_GetCsiUiClkFreq(void)
4138 {
4139     uint32_t reg = PCC_REG(kCLOCK_CsiClkUi);
4140     return CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4141 }
4142 
4143 /*!
4144  * @brief Gets the CSI clk_esc clock frequency.
4145  *
4146  * @return  Clock frequency; If the clock is invalid, returns 0.
4147  */
CLOCK_GetCsiEscClkFreq(void)4148 uint32_t CLOCK_GetCsiEscClkFreq(void)
4149 {
4150     uint32_t reg = PCC_REG(kCLOCK_CsiClkEsc);
4151     return CLOCK_GetPcc5PlatFreq(PCC_PCS_VAL(reg)) * (PCC_FRAC_VAL(reg) + 1U) / (PCC_PCD_VAL(reg) + 1U);
4152 }
4153 
4154 /* Get selected audio clock frequency for SAI0-1, MQS0. */
CLOCK_GetCm33SaiClkFreq(uint32_t src)4155 static uint32_t CLOCK_GetCm33SaiClkFreq(uint32_t src)
4156 {
4157     uint32_t freq;
4158 
4159     switch (src)
4160     {
4161         case 0U:
4162             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd2Div1Clk);
4163             break;
4164         case 1U:
4165             freq = CLOCK_GetRtdAudClkFreq();
4166             break;
4167         case 2U:
4168             freq = CLOCK_GetLpavAudClkFreq();
4169             break;
4170         case 3U:
4171             freq = CLOCK_GetSysOscFreq();
4172             break;
4173         default:
4174             assert(false);
4175             freq = 0U;
4176             break;
4177     }
4178 
4179     return freq;
4180 }
4181 
4182 /* Get selected audio clock frequency for SAI2-3. */
CLOCK_GetFusionSaiClkFreq(uint32_t instance,uint32_t src)4183 static uint32_t CLOCK_GetFusionSaiClkFreq(uint32_t instance, uint32_t src)
4184 {
4185     uint32_t freq;
4186 
4187     switch (src)
4188     {
4189         case 0U:
4190             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd2Div1Clk);
4191             break;
4192         case 1U:
4193             freq = CLOCK_GetMclkFreq(1);
4194             break;
4195         case 2U:
4196             freq = (instance == 2U) ? CLOCK_GetSaiRxBclkFreq(3) : CLOCK_GetSaiTxBclkFreq(2);
4197             break;
4198         case 3U:
4199             freq = CLOCK_GetSysOscFreq();
4200             break;
4201         default:
4202             assert(false);
4203             freq = 0U;
4204             break;
4205     }
4206 
4207     return freq;
4208 }
4209 
4210 /* Get selected audio clock frequency for SAI4-5, MQS1. */
CLOCK_GetAdSaiClkFreq(uint32_t src)4211 static uint32_t CLOCK_GetAdSaiClkFreq(uint32_t src)
4212 {
4213     uint32_t freq;
4214 
4215     switch (src)
4216     {
4217         case 0U:
4218             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd1Div1Clk);
4219             break;
4220         case 1U:
4221             freq = CLOCK_GetAdAudClkFreq();
4222             break;
4223         case 2U:
4224             freq = CLOCK_GetLpavAudClkFreq();
4225             break;
4226         case 3U:
4227             freq = CLOCK_GetSysOscFreq();
4228             break;
4229         default:
4230             assert(false);
4231             freq = 0U;
4232             break;
4233     }
4234 
4235     return freq;
4236 }
4237 
4238 /* Get selected audio clock frequency for SAI6-7, SPDIF. */
CLOCK_GetLpavSaiClkFreq(uint32_t src)4239 static uint32_t CLOCK_GetLpavSaiClkFreq(uint32_t src)
4240 {
4241     uint32_t freq;
4242 
4243     switch (src)
4244     {
4245         case 0U:
4246             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd2Div1Clk);
4247             break;
4248         case 1U:
4249             freq = CLOCK_GetPll3AsyncFreq(kCGC_AsyncPfd1Div1Clk);
4250             break;
4251         case 2U:
4252             freq = CLOCK_GetRtdAudClkFreq();
4253             break;
4254         case 3U:
4255             freq = CLOCK_GetAdAudClkFreq();
4256             break;
4257         case 4U:
4258             freq = CLOCK_GetLpavAudClkFreq();
4259             break;
4260         case 5U:
4261             freq = CLOCK_GetSysOscFreq();
4262             break;
4263         default:
4264             assert(false);
4265             freq = 0U;
4266             break;
4267     }
4268 
4269     return freq;
4270 }
4271 
4272 /*!
4273  * @brief Gets the audio clock frequency in RTD.
4274  *
4275  * @return  Clock frequency; If the clock is invalid, returns 0.
4276  */
CLOCK_GetRtdAudClkFreq(void)4277 uint32_t CLOCK_GetRtdAudClkFreq(void)
4278 {
4279     uint32_t freq;
4280 
4281     switch (CGC_RTD->AUD_CLK0 & CGC_AUD_CLK0_AUD_CLK0_MASK)
4282     {
4283         case (uint32_t)kCGC_RtdAudClkSrcExtMclk0:
4284             freq = CLOCK_GetMclkFreq(0);
4285             break;
4286         case (uint32_t)kCGC_RtdAudClkSrcExtMclk1:
4287             freq = CLOCK_GetMclkFreq(1);
4288             break;
4289         case (uint32_t)kCGC_RtdAudClkSrcSai0RxBclk:
4290             freq = CLOCK_GetSaiRxBclkFreq(0);
4291             break;
4292         case (uint32_t)kCGC_RtdAudClkSrcSai0TxBclk:
4293             freq = CLOCK_GetSaiTxBclkFreq(0);
4294             break;
4295         case (uint32_t)kCGC_RtdAudClkSrcSai1RxBclk:
4296             freq = CLOCK_GetSaiRxBclkFreq(1);
4297             break;
4298         case (uint32_t)kCGC_RtdAudClkSrcSai1TxBclk:
4299             freq = CLOCK_GetSaiTxBclkFreq(1);
4300             break;
4301         case (uint32_t)kCGC_RtdAudClkSrcSai2RxBclk:
4302             freq = CLOCK_GetSaiRxBclkFreq(2);
4303             break;
4304         case (uint32_t)kCGC_RtdAudClkSrcSai2TxBclk:
4305             freq = CLOCK_GetSaiTxBclkFreq(2);
4306             break;
4307         case (uint32_t)kCGC_RtdAudClkSrcSai3RxBclk:
4308             freq = CLOCK_GetSaiRxBclkFreq(3);
4309             break;
4310         case (uint32_t)kCGC_RtdAudClkSrcSai3TxBclk:
4311             freq = CLOCK_GetSaiTxBclkFreq(3);
4312             break;
4313         default:
4314             freq = 0U;
4315             break;
4316     }
4317 
4318     return freq;
4319 }
4320 
4321 /*!
4322  * @brief Gets the audio clock frequency in AD.
4323  *
4324  * @return  Clock frequency; If the clock is invalid, returns 0.
4325  */
CLOCK_GetAdAudClkFreq(void)4326 uint32_t CLOCK_GetAdAudClkFreq(void)
4327 {
4328     uint32_t freq;
4329 
4330     switch (CGC_AD->AUD_CLK1 & CGC_AD_AUD_CLK1_AUD_CLK1_MASK)
4331     {
4332         case (uint32_t)kCGC_AdAudClkSrcExtMclk2:
4333             freq = CLOCK_GetMclkFreq(2);
4334             break;
4335         case (uint32_t)kCGC_AdAudClkSrcSai4RxBclk:
4336             freq = CLOCK_GetSaiRxBclkFreq(4);
4337             break;
4338         case (uint32_t)kCGC_AdAudClkSrcSai4TxBclk:
4339             freq = CLOCK_GetSaiTxBclkFreq(4);
4340             break;
4341         case (uint32_t)kCGC_AdAudClkSrcSai5RxBclk:
4342             freq = CLOCK_GetSaiRxBclkFreq(5);
4343             break;
4344         case (uint32_t)kCGC_AdAudClkSrcSai5TxBclk:
4345             freq = CLOCK_GetSaiTxBclkFreq(5);
4346             break;
4347         default:
4348             freq = 0U;
4349             break;
4350     }
4351 
4352     return freq;
4353 }
4354 
4355 /*!
4356  * @brief Gets the audio clock frequency in LPAV.
4357  *
4358  * @return  Clock frequency; If the clock is invalid, returns 0.
4359  */
CLOCK_GetLpavAudClkFreq(void)4360 uint32_t CLOCK_GetLpavAudClkFreq(void)
4361 {
4362     uint32_t freq;
4363 
4364     switch (CGC_LPAV->AUD_CLK2 & CGC_LPAV_AUD_CLK2_AUD_CLK2_MASK)
4365     {
4366         case (uint32_t)kCGC_LpavAudClkSrcExtMclk3:
4367             freq = CLOCK_GetMclkFreq(3);
4368             break;
4369         case (uint32_t)kCGC_LpavAudClkSrcSai6RxBclk:
4370             freq = CLOCK_GetSaiRxBclkFreq(6);
4371             break;
4372         case (uint32_t)kCGC_LpavAudClkSrcSai6TxBclk:
4373             freq = CLOCK_GetSaiTxBclkFreq(6);
4374             break;
4375         case (uint32_t)kCGC_LpavAudClkSrcSai7RxBclk:
4376             freq = CLOCK_GetSaiRxBclkFreq(7);
4377             break;
4378         case (uint32_t)kCGC_LpavAudClkSrcSai7TxBclk:
4379             freq = CLOCK_GetSaiTxBclkFreq(7);
4380             break;
4381         case (uint32_t)kCGC_LpavAudClkSrcSpdifRx:
4382             freq = CLOCK_GetSpdifRxFreq();
4383             break;
4384         default:
4385             freq = 0U;
4386             break;
4387     }
4388 
4389     return freq;
4390 }
4391 
4392 /*!
4393  * @brief Gets the SAI clock frequency.
4394  *
4395  * @param instance The SAI instance (0-7).
4396  * @return  Clock frequency; If the clock is invalid, returns 0.
4397  */
CLOCK_GetSaiFreq(uint32_t instance)4398 uint32_t CLOCK_GetSaiFreq(uint32_t instance)
4399 {
4400     uint32_t src;
4401     uint32_t freq;
4402 
4403     if (instance <= 1U)
4404     {
4405         src  = (CGC_RTD->SAI3_0_CLK & ((uint32_t)CGC_SAI3_0_CLK_SAI0CLK_MASK << (8U * instance))) >> (8U * instance);
4406         freq = CLOCK_GetCm33SaiClkFreq(src);
4407     }
4408     else if (instance <= 3U)
4409     {
4410         src  = (CGC_RTD->SAI3_0_CLK & ((uint32_t)CGC_SAI3_0_CLK_SAI0CLK_MASK << (8U * instance))) >> (8U * instance);
4411         freq = CLOCK_GetFusionSaiClkFreq(instance, src);
4412     }
4413     else if (instance <= 5U)
4414     {
4415         instance -= 4U;
4416         src  = (CGC_AD->SAI5_4_CLK & ((uint32_t)CGC_AD_SAI5_4_CLK_SAI4CLK_MASK << (8U * instance))) >> (8U * instance);
4417         freq = CLOCK_GetAdSaiClkFreq(src);
4418     }
4419     else if (instance <= 7U)
4420     {
4421         instance -= 6U;
4422         src =
4423             (CGC_LPAV->SAI7_6_CLK & ((uint32_t)CGC_LPAV_SAI7_6_CLK_SAI6CLK_MASK << (8U * instance))) >> (8U * instance);
4424         freq = CLOCK_GetLpavSaiClkFreq(src);
4425     }
4426     else
4427     {
4428         freq = (uint32_t)0;
4429         assert(false);
4430     }
4431 
4432     return freq;
4433 }
4434 
4435 /*!
4436  * @brief Gets the SPDIF clock frequency.
4437  *
4438  * @return  Clock frequency; If the clock is invalid, returns 0.
4439  */
CLOCK_GetSpdifFreq(void)4440 uint32_t CLOCK_GetSpdifFreq(void)
4441 {
4442     return CLOCK_GetLpavSaiClkFreq(CGC_LPAV->SPDIFCLK & CGC_LPAV_SPDIFCLK_SPDIFCLK_MASK);
4443 }
4444 
4445 /*!
4446  * @brief Gets the MQS clock frequency.
4447  *
4448  * @param instance The MQS instance (0-1).
4449  * @return  Clock frequency; If the clock is invalid, returns 0.
4450  */
CLOCK_GetMqsFreq(uint32_t instance)4451 uint32_t CLOCK_GetMqsFreq(uint32_t instance)
4452 {
4453     uint32_t freq;
4454 
4455     if (instance == 0U)
4456     {
4457         freq = CLOCK_GetCm33SaiClkFreq(CGC_RTD->MQS0CLK & CGC_MQS0CLK_MQS0CLK_MASK);
4458     }
4459     else if (instance == 1U)
4460     {
4461         freq = CLOCK_GetAdSaiClkFreq(CGC_AD->MQS1CLK & CGC_AD_MQS1CLK_MQS1CLK_MASK);
4462     }
4463     else
4464     {
4465         assert(false);
4466         freq = 0U;
4467     }
4468 
4469     return freq;
4470 }
4471 
4472 /*!
4473  * @brief Gets the EMICFIL clock frequency.
4474  *
4475  * @return  Clock frequency; If the clock is invalid, returns 0.
4476  */
CLOCK_GetMicfilFreq(void)4477 uint32_t CLOCK_GetMicfilFreq(void)
4478 {
4479     uint32_t freq;
4480 
4481     switch (CGC_RTD->EMICFIL & CGC_EMICFIL_MICFILCLK_MASK)
4482     {
4483         case 0U:
4484             freq = CLOCK_GetPll1AsyncFreq(kCGC_AsyncPfd2Div1Clk);
4485             break;
4486         case 1U:
4487             freq = CLOCK_GetFroFreq() / 8U;
4488             break;
4489         case 2U:
4490             freq = CLOCK_GetSysOscFreq();
4491             break;
4492         case 3U:
4493             freq = CLOCK_GetMclkFreq(1);
4494             break;
4495         case 4U:
4496             freq = CLOCK_GetRtcOscFreq();
4497             break;
4498         case 5U:
4499             freq = CLOCK_GetLpOscFreq();
4500             break;
4501         default:
4502             freq = 0U;
4503             break;
4504     }
4505 
4506     return freq;
4507 }
4508 
4509 /*!
4510  * @brief Gets the MRT clock frequency.
4511  *
4512  * @return  Clock frequency; If the clock is invalid, returns 0.
4513  */
CLOCK_GetMrtFreq(void)4514 uint32_t CLOCK_GetMrtFreq(void)
4515 {
4516     return CLOCK_GetFusionDspBusClkFreq();
4517 }
4518