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