1 /*
2  * Copyright 2019-2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_clock.h"
9 #include "fsl_pmu.h"
10 #include "fsl_anatop_ai.h"
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.clock"
14 #endif
15 
16 /*******************************************************************************
17  * Definitions
18  ******************************************************************************/
19 /* To make full use of CM7 hardware FPU, use double instead of uint64_t in clock driver to
20 achieve better performance, it is depend on the IDE Floating point settings, if double precision is selected
21 in IDE, clock_64b_t will switch to double type automatically. only support IAR and MDK here */
22 #if __FPU_USED
23 
24 #if (defined(__ICCARM__))
25 
26 #if (__ARMVFP__ >= __ARMFPV5__) && \
27     (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/
28 typedef double clock_64b_t;
29 #else
30 typedef uint64_t clock_64b_t;
31 #endif
32 
33 #elif (defined(__GNUC__))
34 
35 #if (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/
36 typedef double clock_64b_t;
37 #else
38 typedef uint64_t clock_64b_t;
39 #endif
40 
41 #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
42 
43 #if defined __TARGET_FPU_FPV5_D16
44 typedef double clock_64b_t;
45 #else
46 typedef uint64_t clock_64b_t;
47 #endif
48 
49 #else
50 typedef uint64_t clock_64b_t;
51 #endif
52 
53 #else
54 typedef uint64_t clock_64b_t;
55 #endif
56 
57 #define PLL_AI_CTRL0_REG     kAI_PLL1G_CTRL0
58 #define PLL_AI_CTRL0_SET_REG kAI_PLL1G_CTRL0_SET
59 #define PLL_AI_CTRL0_CLR_REG kAI_PLL1G_CTRL0_CLR
60 #define PLL_AI_CTRL1_REG     kAI_PLL1G_CTRL1
61 #define PLL_AI_CTRL1_SET_REG kAI_PLL1G_CTRL1_SET
62 #define PLL_AI_CTRL1_CLR_REG kAI_PLL1G_CTRL1_CLR
63 #define PLL_AI_CTRL2_REG     kAI_PLL1G_CTRL2
64 #define PLL_AI_CTRL2_SET_REG kAI_PLL1G_CTRL2_SET
65 #define PLL_AI_CTRL2_CLR_REG kAI_PLL1G_CTRL2_CLR
66 #define PLL_AI_CTRL3_REG     kAI_PLL1G_CTRL3
67 #define PLL_AI_CTRL3_SET_REG kAI_PLL1G_CTRL3_SET
68 #define PLL_AI_CTRL3_CLR_REG kAI_PLL1G_CTRL3_CLR
69 
70 #define PLL_AI_CTRL0_HOLD_RING_OFF_MASK AI_PLL1G_CTRL0_HOLD_RING_OFF_MASK
71 
72 #define PLL_AI_CTRL0_POWER_UP_MASK AI_PLL1G_CTRL0_POWER_UP_MASK
73 
74 #define PLL_AI_CTRL0_ENABLE_MASK AI_PLL1G_CTRL0_ENABLE_MASK
75 
76 #define PLL_AI_CTRL0_BYPASS_MASK AI_PLL1G_CTRL0_BYPASS_MASK
77 
78 #define PLL_AI_CTRL0_PLL_REG_EN_MASK AI_PLL1G_CTRL0_PLL_REG_EN_MASK
79 /*******************************************************************************
80  * Variables
81  ******************************************************************************/
82 
83 /*******************************************************************************
84  * Prototypes
85  ******************************************************************************/
86 static void ANATOP_PllSetPower(anatop_ai_itf_t itf, bool enable);
87 static void ANATOP_PllBypass(anatop_ai_itf_t itf, bool bypass);
88 static void ANATOP_PllEnablePllReg(anatop_ai_itf_t itf, bool enable);
89 static void ANATOP_PllHoldRingOff(anatop_ai_itf_t itf, bool off);
90 static void ANATOP_PllToggleHoldRingOff(anatop_ai_itf_t itf, uint32_t delay_us);
91 static void ANATOP_PllEnableClk(anatop_ai_itf_t itf, bool enable);
92 static void ANATOP_PllConfigure(anatop_ai_itf_t itf,
93                                 uint8_t div,
94                                 uint32_t numer,
95                                 uint8_t post_div,
96                                 uint32_t denom,
97                                 const clock_pll_ss_config_t *ss);
98 static void ANATOP_AudioPllGate(bool enable);
99 static void ANATOP_AudioPllSwEnClk(bool enable);
100 static void ANATOP_VideoPllGate(bool enable);
101 static void ANATOP_VideoPllSwEnClk(bool enable);
102 static void ANATOP_SysPll1Gate(bool enable);
103 static void ANATOP_SysPll1Div2En(bool enable);
104 static void ANATOP_SysPll1Div5En(bool enable);
105 static void ANATOP_SysPll1SwEnClk(bool enable);
106 static void ANATOP_SysPll1WaitStable(void);
107 static void ANATOP_PllEnableSs(anatop_ai_itf_t itf, bool enable);
108 #ifndef GET_FREQ_FROM_OBS
109 static uint32_t CLOCK_GetAvPllFreq(clock_pll_t pll);
110 #endif
111 /*******************************************************************************
112  * Code
113  ******************************************************************************/
114 
115 #define ARM_PLL_DIV_SEL_MIN 104
116 #define ARM_PLL_DIV_SEL_MAX 208
117 
CLOCK_InitArmPll(const clock_arm_pll_config_t * config)118 void CLOCK_InitArmPll(const clock_arm_pll_config_t *config)
119 {
120     assert((config->loopDivider <= (uint32_t)ARM_PLL_DIV_SEL_MAX) &&
121            (config->loopDivider >= (uint32_t)ARM_PLL_DIV_SEL_MIN));
122 
123     uint32_t reg;
124 
125     if (((ANADIG_PLL->ARM_PLL_CTRL & ANADIG_PLL_ARM_PLL_CTRL_POWERUP_MASK) != 0UL) &&
126         ((ANADIG_PLL->ARM_PLL_CTRL & ANADIG_PLL_ARM_PLL_CTRL_DIV_SELECT_MASK) ==
127          ANADIG_PLL_ARM_PLL_CTRL_DIV_SELECT(config->loopDivider)) &&
128         ((ANADIG_PLL->ARM_PLL_CTRL & ANADIG_PLL_ARM_PLL_CTRL_POST_DIV_SEL_MASK) ==
129          ANADIG_PLL_ARM_PLL_CTRL_POST_DIV_SEL(config->postDivider)))
130     {
131         /* no need to reconfigure the PLL if all the configuration is the same */
132         if ((ANADIG_PLL->ARM_PLL_CTRL & ANADIG_PLL_ARM_PLL_CTRL_ENABLE_CLK_MASK) == 0UL)
133         {
134             ANADIG_PLL->ARM_PLL_CTRL |= ANADIG_PLL_ARM_PLL_CTRL_ENABLE_CLK_MASK;
135         }
136         if ((ANADIG_PLL->ARM_PLL_CTRL & ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_GATE_MASK) != 0UL)
137         {
138             ANADIG_PLL->ARM_PLL_CTRL &= ~ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_GATE_MASK;
139         }
140         return;
141     }
142 
143     PMU_StaticEnablePllLdo(ANADIG_PMU);
144 
145     reg = ANADIG_PLL->ARM_PLL_CTRL & (~ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_STABLE_MASK);
146     if ((reg & (ANADIG_PLL_ARM_PLL_CTRL_POWERUP_MASK | ANADIG_PLL_ARM_PLL_CTRL_ENABLE_CLK_MASK)) != 0UL)
147     {
148         /* Power down the PLL. */
149         reg &= ~(ANADIG_PLL_ARM_PLL_CTRL_POWERUP_MASK | ANADIG_PLL_ARM_PLL_CTRL_ENABLE_CLK_MASK);
150         reg |= ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_GATE_MASK;
151         ANADIG_PLL->ARM_PLL_CTRL = reg;
152     }
153 
154     /* Set the configuration. */
155     reg &= ~(ANADIG_PLL_ARM_PLL_CTRL_DIV_SELECT_MASK | ANADIG_PLL_ARM_PLL_CTRL_POST_DIV_SEL_MASK);
156     reg |= (ANADIG_PLL_ARM_PLL_CTRL_DIV_SELECT(config->loopDivider) |
157             ANADIG_PLL_ARM_PLL_CTRL_POST_DIV_SEL(config->postDivider)) |
158            ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_GATE_MASK | ANADIG_PLL_ARM_PLL_CTRL_POWERUP_MASK |
159            ANADIG_PLL_ARM_PLL_CTRL_HOLD_RING_OFF_MASK;
160     ANADIG_PLL->ARM_PLL_CTRL = reg;
161     __DSB();
162     __ISB();
163     SDK_DelayAtLeastUs(30, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
164 
165     reg &= ~ANADIG_PLL_SYS_PLL2_CTRL_HOLD_RING_OFF_MASK;
166     ANADIG_PLL->ARM_PLL_CTRL = reg;
167     /* Wait for the PLL stable, */
168     while (0U == (ANADIG_PLL->ARM_PLL_CTRL & ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_STABLE_MASK))
169     {
170     }
171 
172     /* Enable and ungate the clock. */
173     reg |= ANADIG_PLL_ARM_PLL_CTRL_ENABLE_CLK_MASK;
174     reg &= ~ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_GATE_MASK;
175     ANADIG_PLL->ARM_PLL_CTRL = reg;
176 }
177 
CLOCK_DeinitArmPll(void)178 void CLOCK_DeinitArmPll(void)
179 {
180     uint32_t reg = ANADIG_PLL->ARM_PLL_CTRL & (~ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_STABLE_MASK);
181 
182     reg &= ~(ANADIG_PLL_ARM_PLL_CTRL_POWERUP_MASK | ANADIG_PLL_ARM_PLL_CTRL_ENABLE_CLK_MASK);
183     reg |= ANADIG_PLL_ARM_PLL_CTRL_ARM_PLL_GATE_MASK;
184     ANADIG_PLL->ARM_PLL_CTRL = reg;
185 }
186 
CLOCK_CalcPllSpreadSpectrum(uint32_t factor,uint32_t range,uint32_t mod,clock_pll_ss_config_t * ss)187 void CLOCK_CalcPllSpreadSpectrum(uint32_t factor, uint32_t range, uint32_t mod, clock_pll_ss_config_t *ss)
188 {
189     assert(ss != NULL);
190 
191     ss->stop = (uint16_t)(factor * range / XTAL_FREQ);
192     ss->step = (uint16_t)((mod << 1UL) * (uint32_t)(ss->stop) / XTAL_FREQ);
193 }
194 
195 /* 528PLL */
CLOCK_InitSysPll2(const clock_sys_pll2_config_t * config)196 void CLOCK_InitSysPll2(const clock_sys_pll2_config_t *config)
197 {
198     uint32_t reg;
199 
200     if ((ANADIG_PLL->SYS_PLL2_CTRL & ANADIG_PLL_SYS_PLL2_CTRL_POWERUP_MASK) != 0UL)
201     {
202         if ((config == NULL) ||
203             ((0UL == (ANADIG_PLL->SYS_PLL2_SS & ANADIG_PLL_SYS_PLL2_SS_ENABLE_MASK)) && (!config->ssEnable)) ||
204             ((ANADIG_PLL_SYS_PLL2_SS_ENABLE(config->ssEnable) | ANADIG_PLL_SYS_PLL2_SS_STOP(config->ss->stop) |
205               ANADIG_PLL_SYS_PLL2_SS_STEP(config->ss->step)) == ANADIG_PLL->SYS_PLL2_SS))
206         {
207             /* no need to reconfigure the PLL if all the configuration is the same */
208             if (0UL == (ANADIG_PLL->SYS_PLL2_CTRL & ANADIG_PLL_SYS_PLL2_CTRL_ENABLE_CLK_MASK))
209             {
210                 ANADIG_PLL->SYS_PLL2_CTRL |= ANADIG_PLL_SYS_PLL2_CTRL_ENABLE_CLK_MASK;
211             }
212 
213             if ((ANADIG_PLL->SYS_PLL2_CTRL & ANADIG_PLL_SYS_PLL2_CTRL_SYS_PLL2_GATE_MASK) != 0UL)
214             {
215                 ANADIG_PLL->SYS_PLL2_CTRL &= ~ANADIG_PLL_SYS_PLL2_CTRL_SYS_PLL2_GATE_MASK;
216             }
217             return;
218         }
219     }
220 
221     PMU_StaticEnablePllLdo(ANADIG_PMU);
222     /* Gate all PFDs */
223     ANADIG_PLL->SYS_PLL2_PFD |=
224         ANADIG_PLL_SYS_PLL2_PFD_PFD0_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL2_PFD_PFD1_DIV1_CLKGATE(1) |
225         ANADIG_PLL_SYS_PLL2_PFD_PFD2_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL2_PFD_PFD3_DIV1_CLKGATE(1);
226 
227     reg = ANADIG_PLL->SYS_PLL2_CTRL;
228     if ((reg & (ANADIG_PLL_SYS_PLL2_CTRL_POWERUP_MASK | ANADIG_PLL_SYS_PLL2_CTRL_ENABLE_CLK_MASK)) != 0UL)
229     {
230         /* Power down the PLL. */
231         reg &= ~(ANADIG_PLL_SYS_PLL2_CTRL_POWERUP_MASK | ANADIG_PLL_SYS_PLL2_CTRL_ENABLE_CLK_MASK);
232         reg |= ANADIG_PLL_SYS_PLL2_CTRL_SYS_PLL2_GATE_MASK;
233         ANADIG_PLL->SYS_PLL2_CTRL = reg;
234     }
235 
236     /* Config PLL */
237     if ((config != NULL) && (config->ssEnable) && (config->ss != NULL))
238     {
239         ANADIG_PLL->SYS_PLL2_MFD = ANADIG_PLL_SYS_PLL2_MFD_MFD(config->mfd);
240         ANADIG_PLL->SYS_PLL2_SS  = (ANADIG_PLL_SYS_PLL2_SS_ENABLE_MASK | ANADIG_PLL_SYS_PLL2_SS_STOP(config->ss->stop) |
241                                    ANADIG_PLL_SYS_PLL2_SS_STEP(config->ss->step));
242     }
243 
244     /* REG_EN = 1, GATE = 1, DIV_SEL = 0, POWERUP = 0 */
245     reg                       = ANADIG_PLL_SYS_PLL2_CTRL_PLL_REG_EN(1) | ANADIG_PLL_SYS_PLL2_CTRL_SYS_PLL2_GATE(1);
246     ANADIG_PLL->SYS_PLL2_CTRL = reg;
247     /* Wait until LDO is stable */
248     SDK_DelayAtLeastUs(30, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
249 
250     /* REG_EN = 1, GATE = 1, DIV_SEL = 0, POWERUP = 1, HOLDRING_OFF = 1 */
251     reg |= ANADIG_PLL_SYS_PLL2_CTRL_POWERUP(1) | ANADIG_PLL_SYS_PLL2_CTRL_HOLD_RING_OFF_MASK;
252     ANADIG_PLL->SYS_PLL2_CTRL = reg;
253     SDK_DelayAtLeastUs(250, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
254 
255     /* REG_EN = 1, GATE = 1, DIV_SEL = 0, POWERUP = 1, HOLDRING_OFF = 0 */
256     reg &= ~ANADIG_PLL_SYS_PLL2_CTRL_HOLD_RING_OFF_MASK;
257     ANADIG_PLL->SYS_PLL2_CTRL = reg;
258     /* Wait for PLL stable */
259     while (ANADIG_PLL_SYS_PLL2_CTRL_SYS_PLL2_STABLE_MASK !=
260            (ANADIG_PLL->SYS_PLL2_CTRL & ANADIG_PLL_SYS_PLL2_CTRL_SYS_PLL2_STABLE_MASK))
261     {
262     }
263 
264     /* REG_EN = 1, GATE = 1, DIV_SEL = 0, POWERUP = 1, HOLDRING_OFF = 0, CLK = 1*/
265     reg |= ANADIG_PLL_SYS_PLL2_CTRL_ENABLE_CLK_MASK;
266     ANADIG_PLL->SYS_PLL2_CTRL = reg;
267 
268     /* REG_EN = 1, GATE = 0, DIV_SEL = 0, POWERUP = 1, HOLDRING_OFF = 0, CLK = 1*/
269     reg &= ~ANADIG_PLL_SYS_PLL2_CTRL_SYS_PLL2_GATE_MASK;
270     ANADIG_PLL->SYS_PLL2_CTRL = reg;
271     ANADIG_PLL->SYS_PLL2_PFD &=
272         ~(ANADIG_PLL_SYS_PLL2_PFD_PFD0_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL2_PFD_PFD1_DIV1_CLKGATE(1) |
273           ANADIG_PLL_SYS_PLL2_PFD_PFD2_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL2_PFD_PFD3_DIV1_CLKGATE(1));
274 }
275 
CLOCK_DeinitSysPll2(void)276 void CLOCK_DeinitSysPll2(void)
277 {
278     ANADIG_PLL->SYS_PLL2_PFD |=
279         ANADIG_PLL_SYS_PLL2_PFD_PFD0_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL2_PFD_PFD1_DIV1_CLKGATE(1) |
280         ANADIG_PLL_SYS_PLL2_PFD_PFD2_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL2_PFD_PFD3_DIV1_CLKGATE(1);
281 
282     ANADIG_PLL->SYS_PLL2_CTRL |= ANADIG_PLL_SYS_PLL2_CTRL_SYS_PLL2_GATE_MASK;
283     ANADIG_PLL->SYS_PLL2_CTRL &= ~(ANADIG_PLL_SYS_PLL2_CTRL_ENABLE_CLK_MASK | ANADIG_PLL_SYS_PLL2_CTRL_POWERUP_MASK |
284                                    ANADIG_PLL_SYS_PLL2_CTRL_PLL_REG_EN_MASK);
285 
286     ANADIG_PLL->SYS_PLL2_SS &= ~ANADIG_PLL_SYS_PLL2_SS_ENABLE_MASK;
287 }
288 
289 /*!
290  * brief Check if Sys PLL2 PFD is enabled
291  *
292  * param pfd PFD control name
293  * return PFD bypass status.
294  *         - true: power on.
295  *         - false: power off.
296  * note Only useful in software control mode.
297  */
CLOCK_IsSysPll2PfdEnabled(clock_pfd_t pfd)298 bool CLOCK_IsSysPll2PfdEnabled(clock_pfd_t pfd)
299 {
300     return ((ANADIG_PLL->SYS_PLL2_PFD & (uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_DIV1_CLKGATE_MASK
301                                             << (8UL * (uint8_t)pfd)) == 0U);
302 }
303 
304 #define PFD_FRAC_MIN 12U
305 #define PFD_FRAC_MAX 35U
CLOCK_InitPfd(clock_pll_t pll,clock_pfd_t pfd,uint8_t frac)306 void CLOCK_InitPfd(clock_pll_t pll, clock_pfd_t pfd, uint8_t frac)
307 {
308     volatile uint32_t *pfdCtrl = NULL, *pfdUpdate = NULL, stable;
309     uint32_t regFracVal;
310     bool pfdGated;
311 
312     assert(frac <= (uint8_t)PFD_FRAC_MAX);
313     assert(frac >= (uint8_t)PFD_FRAC_MIN);
314 
315     switch (pll)
316     {
317         case kCLOCK_PllSys2:
318             pfdCtrl   = &ANADIG_PLL->SYS_PLL2_PFD;
319             pfdUpdate = &ANADIG_PLL->SYS_PLL2_UPDATE;
320             break;
321         case kCLOCK_PllSys3:
322             pfdCtrl   = &ANADIG_PLL->SYS_PLL3_PFD;
323             pfdUpdate = &ANADIG_PLL->SYS_PLL3_UPDATE;
324             break;
325         default:
326             /* Wrong input parameter pll. */
327             assert(false);
328             break;
329     }
330 
331     regFracVal = ((*pfdCtrl) & ((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_FRAC_MASK << (8UL * (uint32_t)pfd))) >>
332                  (8UL * (uint32_t)pfd);
333     pfdGated =
334         (bool)(((*pfdCtrl) & ((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_DIV1_CLKGATE_MASK << (8UL * (uint32_t)pfd))) >>
335                (8UL >> (uint32_t)pfd));
336     if ((regFracVal == (uint32_t)frac) && (!pfdGated))
337     {
338         return;
339     }
340 
341     stable = *pfdCtrl & ((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_STABLE_MASK << (8UL * (uint32_t)pfd));
342     *pfdCtrl |= ((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_DIV1_CLKGATE_MASK << (8UL * (uint32_t)pfd));
343 
344     /* all pfds support to be updated on-the-fly after corresponding PLL is stable */
345     *pfdCtrl &= ~((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_FRAC_MASK << (8UL * (uint32_t)pfd));
346     *pfdCtrl |= (ANADIG_PLL_SYS_PLL2_PFD_PFD0_FRAC(frac) << (8UL * (uint32_t)pfd));
347 
348     *pfdUpdate ^= ((uint32_t)ANADIG_PLL_SYS_PLL2_UPDATE_PFD0_UPDATE_MASK << (uint32_t)pfd);
349     *pfdCtrl &= ~((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_DIV1_CLKGATE_MASK << (8UL * (uint32_t)pfd));
350     /* Wait for stablizing */
351     while (stable == (*pfdCtrl & ((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_STABLE_MASK << (8UL * (uint32_t)pfd))))
352     {
353     }
354 }
355 
356 /*!
357  * brief De-initialize selected PLL PFD.
358  *
359  * param pll Which PLL of targeting PFD to be operated.
360  * param pfd Which PFD clock to enable.
361  */
CLOCK_DeinitPfd(clock_pll_t pll,clock_pfd_t pfd)362 void CLOCK_DeinitPfd(clock_pll_t pll, clock_pfd_t pfd)
363 {
364     volatile uint32_t *pfdCtrl = NULL;
365 
366     switch (pll)
367     {
368         case kCLOCK_PllSys2:
369         {
370             pfdCtrl = &ANADIG_PLL->SYS_PLL2_PFD;
371             break;
372         }
373         case kCLOCK_PllSys3:
374         {
375             pfdCtrl = &ANADIG_PLL->SYS_PLL3_PFD;
376             break;
377         }
378         default:
379         {
380             /* Wrong input parameter pll. */
381             assert(false);
382             break;
383         }
384     }
385 
386     /* Clock gate the selected pfd. */
387     *pfdCtrl |= ((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_DIV1_CLKGATE_MASK << (8UL * (uint32_t)pfd));
388 }
389 
390 #ifndef GET_FREQ_FROM_OBS
CLOCK_GetPfdFreq(clock_pll_t pll,clock_pfd_t pfd)391 uint32_t CLOCK_GetPfdFreq(clock_pll_t pll, clock_pfd_t pfd)
392 {
393     uint32_t pllFreq = 0UL, frac = 0UL;
394     assert((pll == kCLOCK_PllSys2) || (pll == kCLOCK_PllSys3));
395 
396     switch (pll)
397     {
398         case kCLOCK_PllSys2:
399             frac    = (ANADIG_PLL->SYS_PLL2_PFD &
400                     ((uint32_t)ANADIG_PLL_SYS_PLL2_PFD_PFD0_FRAC_MASK << (8UL * (uint32_t)pfd)));
401             pllFreq = (uint32_t)SYS_PLL2_FREQ;
402             break;
403         case kCLOCK_PllSys3:
404             frac    = (ANADIG_PLL->SYS_PLL3_PFD &
405                     ((uint32_t)ANADIG_PLL_SYS_PLL3_PFD_PFD0_FRAC_MASK << (8UL * (uint32_t)pfd)));
406             pllFreq = (uint32_t)SYS_PLL3_FREQ;
407             break;
408         default:
409             /* Wrong input parameter pll. */
410             assert(false);
411             break;
412     }
413 
414     frac = frac >> (8UL * (uint32_t)pfd);
415     assert(frac >= (uint32_t)PFD_FRAC_MIN);
416     assert(frac <= (uint32_t)PFD_FRAC_MAX);
417     return ((frac != 0UL) ? (pllFreq / frac * 18UL) : 0UL);
418 }
419 #else
CLOCK_GetPfdFreq(clock_pll_t pll,clock_pfd_t pfd)420 uint32_t CLOCK_GetPfdFreq(clock_pll_t pll, clock_pfd_t pfd)
421 {
422     uint32_t freq = 0;
423     assert((pll == kCLOCK_PllSys2) || (pll == kCLOCK_PllSys3));
424 
425     switch (pll)
426     {
427         case kCLOCK_PllSys2:
428             /* SYS_PLL2_PFD0 OBS index starts from 234 */
429             freq = CLOCK_GetFreqFromObs(pfd + 234, 2);
430             break;
431         case kCLOCK_PllSys3:
432             /* SYS_PLL3_PFD0 OBS index starts from 241 */
433             freq = CLOCK_GetFreqFromObs(pfd + 241, 2);
434             break;
435         default:
436             assert(false);
437     }
438     return freq;
439 }
440 #endif
441 
442 /* 480PLL */
CLOCK_InitSysPll3(void)443 void CLOCK_InitSysPll3(void)
444 {
445     uint32_t reg;
446 
447     if (0UL != (ANADIG_PLL->SYS_PLL3_CTRL & ANADIG_PLL_SYS_PLL3_CTRL_POWERUP_MASK))
448     {
449         /* no need to reconfigure the PLL if all the configuration is the same */
450         if (0UL == (ANADIG_PLL->SYS_PLL3_CTRL & ANADIG_PLL_SYS_PLL3_CTRL_ENABLE_CLK_MASK))
451         {
452             ANADIG_PLL->SYS_PLL3_CTRL |= ANADIG_PLL_SYS_PLL3_CTRL_ENABLE_CLK_MASK;
453         }
454 
455         if (0UL != (ANADIG_PLL->SYS_PLL3_CTRL & ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_GATE_MASK))
456         {
457             ANADIG_PLL->SYS_PLL3_CTRL &= ~ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_GATE_MASK;
458         }
459         return;
460     }
461 
462     PMU_StaticEnablePllLdo(ANADIG_PMU);
463 
464     /* Gate all PFDs */
465     ANADIG_PLL->SYS_PLL3_PFD |=
466         ANADIG_PLL_SYS_PLL3_PFD_PFD0_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL3_PFD_PFD1_DIV1_CLKGATE(1) |
467         ANADIG_PLL_SYS_PLL3_PFD_PFD2_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL3_PFD_PFD3_DIV1_CLKGATE(1);
468     /*
469      * 1. configure PLL registres
470      * 2. Enable internal LDO
471      * 3. Wati LDO stable
472      * 4. Power up PLL, assert hold_ring_off (only needed for avpll)
473      * 5. At half lock time, de-asserted hold_ring_off (only needed for avpll)
474      * 6. Wait PLL lock
475      * 7. Enable clock output, release pfd_gate
476      */
477     reg                       = ANADIG_PLL_SYS_PLL3_CTRL_PLL_REG_EN(1) | ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_GATE(1);
478     ANADIG_PLL->SYS_PLL3_CTRL = reg;
479     SDK_DelayAtLeastUs(30, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
480 
481     reg |= ANADIG_PLL_SYS_PLL3_CTRL_POWERUP(1) | ANADIG_PLL_SYS_PLL3_CTRL_HOLD_RING_OFF_MASK;
482     ANADIG_PLL->SYS_PLL3_CTRL = reg;
483     SDK_DelayAtLeastUs(30, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
484 
485     reg &= ~ANADIG_PLL_SYS_PLL3_CTRL_HOLD_RING_OFF_MASK;
486     ANADIG_PLL->SYS_PLL3_CTRL = reg;
487 
488     /* Wait for PLL stable */
489     while (ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_STABLE_MASK !=
490            (ANADIG_PLL->SYS_PLL3_CTRL & ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_STABLE_MASK))
491     {
492     }
493 
494     reg |= ANADIG_PLL_SYS_PLL3_CTRL_ENABLE_CLK(1) | ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_DIV2(1);
495     ANADIG_PLL->SYS_PLL3_CTRL = reg;
496 
497     reg &= ~ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_GATE_MASK;
498     ANADIG_PLL->SYS_PLL3_CTRL = reg;
499 }
500 
CLOCK_DeinitSysPll3(void)501 void CLOCK_DeinitSysPll3(void)
502 {
503     ANADIG_PLL->SYS_PLL3_PFD |=
504         ANADIG_PLL_SYS_PLL3_PFD_PFD0_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL3_PFD_PFD1_DIV1_CLKGATE(1) |
505         ANADIG_PLL_SYS_PLL3_PFD_PFD2_DIV1_CLKGATE(1) | ANADIG_PLL_SYS_PLL3_PFD_PFD3_DIV1_CLKGATE(1);
506 
507     ANADIG_PLL->SYS_PLL3_CTRL |= ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_GATE_MASK;
508     ANADIG_PLL->SYS_PLL3_CTRL &= ~(ANADIG_PLL_SYS_PLL3_CTRL_ENABLE_CLK_MASK | ANADIG_PLL_SYS_PLL3_CTRL_POWERUP_MASK |
509                                    ANADIG_PLL_SYS_PLL3_CTRL_PLL_REG_EN_MASK);
510 }
511 
512 /*!
513  * brief Check if Sys PLL3 PFD is enabled
514  *
515  * param pfd PFD control name
516  * return PFD bypass status.
517  *         - true: power on.
518  *         - false: power off.
519  * note Only useful in software control mode.
520  */
CLOCK_IsSysPll3PfdEnabled(clock_pfd_t pfd)521 bool CLOCK_IsSysPll3PfdEnabled(clock_pfd_t pfd)
522 {
523     return ((ANADIG_PLL->SYS_PLL3_PFD & (uint32_t)ANADIG_PLL_SYS_PLL3_PFD_PFD0_DIV1_CLKGATE_MASK
524                                             << (8UL * (uint8_t)pfd)) == 0U);
525 }
526 
CLOCK_SetPllBypass(clock_pll_t pll,bool bypass)527 void CLOCK_SetPllBypass(clock_pll_t pll, bool bypass)
528 {
529     switch (pll)
530     {
531         case kCLOCK_PllArm:
532             ANADIG_PLL->ARM_PLL_CTRL = bypass ? (ANADIG_PLL->ARM_PLL_CTRL | ANADIG_PLL_ARM_PLL_CTRL_BYPASS_MASK) :
533                                                 (ANADIG_PLL->ARM_PLL_CTRL & ~ANADIG_PLL_ARM_PLL_CTRL_BYPASS_MASK);
534             break;
535         case kCLOCK_PllSys1:
536             ANATOP_PllBypass(kAI_Itf_1g, bypass);
537             break;
538         case kCLOCK_PllSys2:
539             ANADIG_PLL->SYS_PLL2_CTRL = bypass ? (ANADIG_PLL->SYS_PLL2_CTRL | ANADIG_PLL_SYS_PLL2_CTRL_BYPASS_MASK) :
540                                                  (ANADIG_PLL->SYS_PLL2_CTRL & ~ANADIG_PLL_SYS_PLL2_CTRL_BYPASS_MASK);
541             break;
542         case kCLOCK_PllSys3:
543             ANADIG_PLL->SYS_PLL3_CTRL = bypass ? (ANADIG_PLL->SYS_PLL3_CTRL | ANADIG_PLL_SYS_PLL3_CTRL_BYPASS_MASK) :
544                                                  (ANADIG_PLL->SYS_PLL3_CTRL & ~ANADIG_PLL_SYS_PLL3_CTRL_BYPASS_MASK);
545             break;
546         case kCLOCK_PllAudio:
547             ANATOP_PllBypass(kAI_Itf_Audio, bypass);
548             break;
549         case kCLOCK_PllVideo:
550             ANATOP_PllBypass(kAI_Itf_Video, bypass);
551             break;
552         default:
553             assert(false);
554             break;
555     }
556 }
557 
ANATOP_PllSetPower(anatop_ai_itf_t itf,bool enable)558 static void ANATOP_PllSetPower(anatop_ai_itf_t itf, bool enable)
559 {
560     ANATOP_AI_Write(itf, enable ? PLL_AI_CTRL0_SET_REG : PLL_AI_CTRL0_CLR_REG,
561                     PLL_AI_CTRL0_POWER_UP_MASK | (enable ? PLL_AI_CTRL0_HOLD_RING_OFF_MASK : 0UL));
562 }
563 
ANATOP_PllBypass(anatop_ai_itf_t itf,bool bypass)564 static void ANATOP_PllBypass(anatop_ai_itf_t itf, bool bypass)
565 {
566     ANATOP_AI_Write(itf, bypass ? PLL_AI_CTRL0_SET_REG : PLL_AI_CTRL0_CLR_REG, PLL_AI_CTRL0_BYPASS_MASK);
567 }
568 
ANATOP_PllEnablePllReg(anatop_ai_itf_t itf,bool enable)569 static void ANATOP_PllEnablePllReg(anatop_ai_itf_t itf, bool enable)
570 {
571     ANATOP_AI_Write(itf, enable ? PLL_AI_CTRL0_SET_REG : PLL_AI_CTRL0_CLR_REG, PLL_AI_CTRL0_PLL_REG_EN_MASK);
572 }
573 
ANATOP_PllHoldRingOff(anatop_ai_itf_t itf,bool off)574 static void ANATOP_PllHoldRingOff(anatop_ai_itf_t itf, bool off)
575 {
576     ANATOP_AI_Write(itf, off ? PLL_AI_CTRL0_SET_REG : PLL_AI_CTRL0_CLR_REG, PLL_AI_CTRL0_HOLD_RING_OFF_MASK);
577 }
578 
ANATOP_PllToggleHoldRingOff(anatop_ai_itf_t itf,uint32_t delay_us)579 static void ANATOP_PllToggleHoldRingOff(anatop_ai_itf_t itf, uint32_t delay_us)
580 {
581     ANATOP_PllHoldRingOff(itf, true);
582     SDK_DelayAtLeastUs(delay_us, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
583     ANATOP_PllHoldRingOff(itf, false);
584 }
585 
ANATOP_PllEnableSs(anatop_ai_itf_t itf,bool enable)586 static void ANATOP_PllEnableSs(anatop_ai_itf_t itf, bool enable)
587 {
588     ANATOP_AI_Write(itf, enable ? PLL_AI_CTRL0_SET_REG : PLL_AI_CTRL0_CLR_REG, PLL_AI_CTRL0_ENABLE_MASK);
589 }
590 
ANATOP_PllEnableClk(anatop_ai_itf_t itf,bool enable)591 static void ANATOP_PllEnableClk(anatop_ai_itf_t itf, bool enable)
592 {
593     ANATOP_AI_Write(itf, enable ? PLL_AI_CTRL0_SET_REG : PLL_AI_CTRL0_CLR_REG, PLL_AI_CTRL0_ENABLE_MASK);
594 }
595 
ANATOP_PllConfigure(anatop_ai_itf_t itf,uint8_t div,uint32_t numer,uint8_t post_div,uint32_t denom,const clock_pll_ss_config_t * ss)596 static void ANATOP_PllConfigure(
597     anatop_ai_itf_t itf, uint8_t div, uint32_t numer, uint8_t post_div, uint32_t denom, const clock_pll_ss_config_t *ss)
598 {
599     if (itf != kAI_Itf_1g)
600     {
601         ANATOP_PllSetPower(itf, false);
602     }
603     if (ss != NULL)
604     {
605         ANATOP_AI_Write(itf, PLL_AI_CTRL1_REG,
606                         AUDIO_PLL_SPREAD_SPECTRUM_STEP(ss->step) | AUDIO_PLL_SPREAD_SPECTRUM_STOP(ss->stop) |
607                             AUDIO_PLL_SPREAD_SPECTRUM_ENABLE_MASK);
608     }
609     ANATOP_AI_Write(itf, PLL_AI_CTRL3_REG, denom);
610     ANATOP_AI_Write(itf, PLL_AI_CTRL2_REG, numer);
611     ANATOP_AI_WriteWithMaskShift(itf, PLL_AI_CTRL0_REG, div, 0x7f, 0);
612     if (itf != kAI_Itf_1g)
613     {
614         ANATOP_AI_WriteWithMaskShift(itf, PLL_AI_CTRL0_REG, post_div, 0xE000000UL, 25UL);
615     }
616     ANATOP_PllEnablePllReg(itf, true);
617     SDK_DelayAtLeastUs(100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
618     ANATOP_PllSetPower(itf, true);
619 }
620 
ANATOP_AudioPllGate(bool enable)621 static void ANATOP_AudioPllGate(bool enable)
622 {
623     if (!enable)
624     {
625         ANADIG_PLL->PLL_AUDIO_CTRL &= ~ANADIG_PLL_PLL_AUDIO_CTRL_PLL_AUDIO_GATE_MASK;
626     }
627     else
628     {
629         ANADIG_PLL->PLL_AUDIO_CTRL |= ANADIG_PLL_PLL_AUDIO_CTRL_PLL_AUDIO_GATE_MASK;
630     }
631 }
632 
ANATOP_AudioPllSwEnClk(bool enable)633 static void ANATOP_AudioPllSwEnClk(bool enable)
634 {
635     if (!enable)
636     {
637         ANADIG_PLL->PLL_AUDIO_CTRL &= ~ANADIG_PLL_PLL_AUDIO_CTRL_ENABLE_CLK_MASK;
638     }
639     else
640     {
641         ANADIG_PLL->PLL_AUDIO_CTRL |= ANADIG_PLL_PLL_AUDIO_CTRL_ENABLE_CLK_MASK;
642     }
643 }
644 
CLOCK_InitAudioPllWithFreq(uint32_t freqInMhz,bool ssEnable,uint32_t ssRange,uint32_t ssMod)645 status_t CLOCK_InitAudioPllWithFreq(uint32_t freqInMhz, bool ssEnable, uint32_t ssRange, uint32_t ssMod)
646 {
647     clock_audio_pll_config_t config = {0};
648     config.ssEnable                 = ssEnable;
649 
650     if (kStatus_Success == CLOCK_CalcAvPllFreq(&config, freqInMhz))
651     {
652         if (config.ssEnable)
653         {
654             clock_pll_ss_config_t ss = {0};
655             CLOCK_CalcPllSpreadSpectrum(config.denominator, ssRange, ssMod, &ss);
656             config.ss = &ss;
657         }
658         CLOCK_InitAudioPll(&config);
659         return kStatus_Success;
660     }
661     return kStatus_Fail;
662 }
663 
CLOCK_InitAudioPll(const clock_audio_pll_config_t * config)664 void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
665 {
666     uint32_t reg;
667     bool pllStable = false;
668 
669     PMU_StaticEnablePllLdo(ANADIG_PMU);
670 
671     reg = ANADIG_PLL->PLL_AUDIO_CTRL;
672     if ((reg & (ANADIG_PLL_PLL_AUDIO_CTRL_PLL_AUDIO_STABLE_MASK | ANADIG_PLL_PLL_AUDIO_CTRL_ENABLE_CLK_MASK)) ==
673         (ANADIG_PLL_PLL_AUDIO_CTRL_PLL_AUDIO_STABLE_MASK | ANADIG_PLL_PLL_AUDIO_CTRL_ENABLE_CLK_MASK))
674     {
675         pllStable = true;
676     }
677     /* bypass pll */
678     ANATOP_PllBypass(kAI_Itf_Audio, true);
679 
680     if (pllStable)
681     {
682         /* sw enable clock */
683         ANATOP_AudioPllSwEnClk(false);
684         /* gate clock */
685         ANATOP_AudioPllGate(true);
686         ANATOP_PllEnableClk(kAI_Itf_Audio, false);
687         ANATOP_PllSetPower(kAI_Itf_Audio, false);
688         ANATOP_PllEnablePllReg(kAI_Itf_Audio, false);
689     }
690 
691     ANATOP_AudioPllSwEnClk(true);
692     /* configure pll */
693     ANATOP_PllConfigure(kAI_Itf_Audio, config->loopDivider, config->numerator, config->postDivider, config->denominator,
694                         (config->ssEnable && (config->ss != NULL)) ? config->ss : NULL);
695 
696     /* toggle hold ring off */
697     ANATOP_PllToggleHoldRingOff(kAI_Itf_Audio, 225);
698 
699     /* wait pll stable */
700     do
701     {
702         reg = ANADIG_PLL->PLL_AUDIO_CTRL;
703     } while ((reg & ANADIG_PLL_PLL_AUDIO_CTRL_PLL_AUDIO_STABLE_MASK) !=
704              ANADIG_PLL_PLL_AUDIO_CTRL_PLL_AUDIO_STABLE_MASK); /* wait for PLL locked */
705 
706     /* enabled clock */
707     ANATOP_PllEnableClk(kAI_Itf_Audio, true);
708 
709     /* ungate clock */
710     ANATOP_AudioPllGate(false);
711 
712     ANATOP_PllBypass(kAI_Itf_Audio, false);
713 }
714 
CLOCK_DeinitAudioPll(void)715 void CLOCK_DeinitAudioPll(void)
716 {
717     ANATOP_AudioPllSwEnClk(false);
718     ANATOP_AudioPllGate(true);
719     ANATOP_PllEnableClk(kAI_Itf_Audio, false);
720     ANATOP_PllSetPower(kAI_Itf_Audio, false);
721     ANATOP_PllEnableSs(kAI_Itf_Audio, false);
722     ANATOP_PllEnablePllReg(kAI_Itf_Audio, false);
723 }
724 
CLOCK_GPC_SetAudioPllOutputFreq(const clock_audio_pll_gpc_config_t * config)725 void CLOCK_GPC_SetAudioPllOutputFreq(const clock_audio_pll_gpc_config_t *config)
726 {
727     assert(config != NULL);
728 
729     ANADIG_PLL->PLL_AUDIO_DIV_SELECT  = config->loopDivider;
730     ANADIG_PLL->PLL_AUDIO_NUMERATOR   = config->numerator;
731     ANADIG_PLL->PLL_AUDIO_DENOMINATOR = config->denominator;
732     if ((config->ss != NULL) && config->ssEnable)
733     {
734         ANADIG_PLL->PLL_AUDIO_SS = ANADIG_PLL_PLL_AUDIO_SS_STEP(config->ss->step) |
735                                    ANADIG_PLL_PLL_AUDIO_SS_STOP(config->ss->stop) | ANADIG_PLL_PLL_AUDIO_SS_ENABLE_MASK;
736     }
737 
738     ANADIG_PLL->PLL_AUDIO_CTRL |= ANADIG_PLL_PLL_AUDIO_CTRL_PLL_AUDIO_CONTROL_MODE_MASK;
739 }
740 
ANATOP_VideoPllGate(bool enable)741 static void ANATOP_VideoPllGate(bool enable)
742 {
743     if (!enable)
744     {
745         ANADIG_PLL->PLL_VIDEO_CTRL &= ~ANADIG_PLL_PLL_VIDEO_CTRL_PLL_VIDEO_GATE_MASK;
746     }
747     else
748     {
749         ANADIG_PLL->PLL_VIDEO_CTRL |= ANADIG_PLL_PLL_VIDEO_CTRL_PLL_VIDEO_GATE_MASK;
750     }
751 }
752 
ANATOP_VideoPllSwEnClk(bool enable)753 static void ANATOP_VideoPllSwEnClk(bool enable)
754 {
755     if (!enable)
756     {
757         ANADIG_PLL->PLL_VIDEO_CTRL &= ~ANADIG_PLL_PLL_VIDEO_CTRL_ENABLE_CLK_MASK;
758     }
759     else
760     {
761         ANADIG_PLL->PLL_VIDEO_CTRL |= ANADIG_PLL_PLL_VIDEO_CTRL_ENABLE_CLK_MASK;
762     }
763 }
764 
CLOCK_CalcArmPllFreq(clock_arm_pll_config_t * config,uint32_t freqInMhz)765 status_t CLOCK_CalcArmPllFreq(clock_arm_pll_config_t *config, uint32_t freqInMhz)
766 {
767     assert(config != NULL);
768     uint32_t refFreq = ((XTAL_FREQ / 1000000UL) * 104UL / 4UL); /* MHz */
769     assert((freqInMhz <= refFreq) && (freqInMhz >= 156UL));
770 
771     /*
772      * ARM_PLL  (156Mhz - 624MHz configureable )
773      * freqInMhz = osc_freq * loopDivider / (2 * postDivider)
774      *   - loopDivider:  104 - 208
775      *   postDivider:
776      *     0 - divide by 8; 1 - divide by 4
777      */
778 
779     if (freqInMhz >= refFreq)
780     {
781         config->loopDivider = 208;
782         config->postDivider = kCLOCK_PllPostDiv4;
783     }
784     else if (freqInMhz >= (refFreq >> 1UL))
785     {
786         config->postDivider = kCLOCK_PllPostDiv4;
787         config->loopDivider = freqInMhz / 3UL;
788     }
789     else
790     {
791         config->postDivider = kCLOCK_PllPostDiv8;
792         config->loopDivider = freqInMhz * 2UL / 3UL;
793     }
794 
795     return kStatus_Success;
796 }
797 
CLOCK_InitArmPllWithFreq(uint32_t freqInMhz)798 status_t CLOCK_InitArmPllWithFreq(uint32_t freqInMhz)
799 {
800     clock_arm_pll_config_t config;
801     if (kStatus_Success == CLOCK_CalcArmPllFreq(&config, freqInMhz))
802     {
803         CLOCK_InitArmPll(&config);
804         return kStatus_Success;
805     }
806     return kStatus_Fail;
807 }
808 
CLOCK_CalcAvPllFreq(clock_av_pll_config_t * config,uint32_t freqInMhz)809 status_t CLOCK_CalcAvPllFreq(clock_av_pll_config_t *config, uint32_t freqInMhz)
810 {
811     assert(config != NULL);
812 
813     uint32_t refFreq = (XTAL_FREQ / 1000000UL) * 54UL; /* MHz */
814 
815     assert((freqInMhz <= refFreq) && (freqInMhz > 20UL));
816 
817     /*
818      * AUDIO_PLL/VIDEO_PLL  (20.3125MHZ--- 1300MHZ configureable )
819      * freqInMhz = osc_freq * (loopDivider + numerator / (2^28 - 1) ) / 2^postDivider
820      *   - loopDivider:  27---54
821      *   - postDivider: 0---5
822      *   - numerator is a signed number, 30 bit,  numer[29] is the sign bit, such as +1--->0x00000001; -1---> 0x20000001
823      * such as: div_sel = 27, numer = 0x026EEEEF, post_div =0, fref = 24.0MHZ, output_fre =24.0*(27 + 40824559/(2^28 -
824      * 1))/2^0 = 651.65M such as: div_sel = 33, numer = 0x0F0AAAAA, post_div =0, fref = 19.2MHZ, output_fre =19.2*(33 +
825      * 252357290/(2^28 - 1))/2^0= 651.65M
826      */
827 
828     config->denominator = 0x0FFFFFFF;
829 
830     if (freqInMhz >= refFreq)
831     {
832         config->postDivider = 0;
833         config->loopDivider = 54;
834         config->numerator   = 0;
835     }
836     else if (freqInMhz >= (refFreq >> 1))
837     {
838         config->postDivider = 0;
839         config->loopDivider = (uint8_t)(freqInMhz / 24UL);
840         config->numerator   = (config->denominator / 24UL) * (freqInMhz % 24UL);
841     }
842     else if (freqInMhz >= (refFreq >> 2))
843     {
844         config->postDivider = 1;
845         config->loopDivider = (uint8_t)(freqInMhz / 12UL);
846         config->numerator   = (config->denominator / 12UL) * (freqInMhz % 12UL);
847     }
848     else if (freqInMhz >= (refFreq >> 3))
849     {
850         config->postDivider = 2;
851         config->loopDivider = (uint8_t)(freqInMhz / 6UL);
852         config->numerator   = (config->denominator / 6UL) * (freqInMhz % 6UL);
853     }
854     else if (freqInMhz >= (refFreq >> 4))
855     {
856         config->postDivider = 3;
857         config->loopDivider = (uint8_t)(freqInMhz / 3UL);
858         config->numerator   = (config->denominator / 3UL) * (freqInMhz % 3UL);
859     }
860     else if (freqInMhz >= (refFreq >> 5))
861     {
862         config->postDivider = 4;
863         config->loopDivider = (uint8_t)(freqInMhz * 2UL / 3UL);
864         config->numerator   = (config->denominator * 2UL / 3UL) * (freqInMhz * 2UL % 3UL);
865     }
866     else if (freqInMhz > (refFreq >> 6))
867     {
868         config->postDivider = 5;
869         config->loopDivider = (uint8_t)(freqInMhz * 4UL / 3UL);
870         config->numerator   = (config->denominator * 4UL / 3UL) * (freqInMhz * 4UL % 3UL);
871     }
872     else
873     {
874         return kStatus_Fail;
875     }
876     return kStatus_Success;
877 }
878 
CLOCK_InitVideoPllWithFreq(uint32_t freqInMhz,bool ssEnable,uint32_t ssRange,uint32_t ssMod)879 status_t CLOCK_InitVideoPllWithFreq(uint32_t freqInMhz, bool ssEnable, uint32_t ssRange, uint32_t ssMod)
880 {
881     clock_video_pll_config_t config = {0};
882     config.ssEnable                 = ssEnable;
883 
884     if (kStatus_Success == CLOCK_CalcAvPllFreq(&config, freqInMhz))
885     {
886         if (config.ssEnable)
887         {
888             clock_pll_ss_config_t ss = {0};
889             CLOCK_CalcPllSpreadSpectrum(config.denominator, ssRange, ssMod, &ss);
890             config.ss = &ss;
891         }
892         CLOCK_InitVideoPll(&config);
893         return kStatus_Success;
894     }
895     return kStatus_Fail;
896 }
897 
CLOCK_InitVideoPll(const clock_video_pll_config_t * config)898 void CLOCK_InitVideoPll(const clock_video_pll_config_t *config)
899 {
900     uint32_t reg;
901     bool pllStable = false;
902 
903     PMU_StaticEnablePllLdo(ANADIG_PMU);
904 
905     reg = ANADIG_PLL->PLL_VIDEO_CTRL;
906     if ((reg & (ANADIG_PLL_PLL_VIDEO_CTRL_PLL_VIDEO_STABLE_MASK | ANADIG_PLL_PLL_VIDEO_CTRL_ENABLE_CLK_MASK)) ==
907         (ANADIG_PLL_PLL_VIDEO_CTRL_PLL_VIDEO_STABLE_MASK | ANADIG_PLL_PLL_VIDEO_CTRL_ENABLE_CLK_MASK))
908     {
909         pllStable = true;
910     }
911     /* bypass pll */
912     ANATOP_PllBypass(kAI_Itf_Video, true);
913 
914     if (pllStable)
915     {
916         /* sw enable clock */
917         ANATOP_VideoPllSwEnClk(false);
918         /* gate clock */
919         ANATOP_VideoPllGate(true);
920         ANATOP_PllEnableClk(kAI_Itf_Video, false);
921         ANATOP_PllSetPower(kAI_Itf_Video, false);
922         ANATOP_PllEnablePllReg(kAI_Itf_Video, false);
923     }
924 
925     ANATOP_VideoPllSwEnClk(true);
926     /* configure pll */
927     ANATOP_PllConfigure(kAI_Itf_Video, config->loopDivider, config->numerator, config->postDivider, config->denominator,
928                         (config->ssEnable && (config->ss != NULL)) ? config->ss : NULL);
929 
930     /* toggle hold ring off */
931     ANATOP_PllToggleHoldRingOff(kAI_Itf_Video, 225);
932 
933     /* wait pll stable */
934     do
935     {
936         reg = ANADIG_PLL->PLL_VIDEO_CTRL;
937     } while ((reg & ANADIG_PLL_PLL_VIDEO_CTRL_PLL_VIDEO_STABLE_MASK) !=
938              ANADIG_PLL_PLL_VIDEO_CTRL_PLL_VIDEO_STABLE_MASK); /* wait for PLL locked */
939 
940     /* enabled clock */
941     ANATOP_PllEnableClk(kAI_Itf_Video, true);
942 
943     /* ungate clock */
944     ANATOP_VideoPllGate(false);
945 
946     ANATOP_PllBypass(kAI_Itf_Video, false);
947 }
948 
CLOCK_DeinitVideoPll(void)949 void CLOCK_DeinitVideoPll(void)
950 {
951     ANATOP_VideoPllSwEnClk(false);
952     ANATOP_VideoPllGate(true);
953     ANATOP_PllEnableClk(kAI_Itf_Video, false);
954     ANATOP_PllSetPower(kAI_Itf_Video, false);
955     ANATOP_PllEnableSs(kAI_Itf_Video, false);
956     ANATOP_PllEnablePllReg(kAI_Itf_Video, false);
957 }
958 
CLOCK_GPC_SetVideoPllOutputFreq(const clock_video_pll_gpc_config_t * config)959 void CLOCK_GPC_SetVideoPllOutputFreq(const clock_video_pll_gpc_config_t *config)
960 {
961     assert(config != NULL);
962 
963     ANADIG_PLL->PLL_VIDEO_DIV_SELECT  = config->loopDivider;
964     ANADIG_PLL->PLL_VIDEO_NUMERATOR   = config->numerator;
965     ANADIG_PLL->PLL_VIDEO_DENOMINATOR = config->denominator;
966 
967     if ((config->ss != NULL) && config->ssEnable)
968     {
969         ANADIG_PLL->PLL_VIDEO_SS = ANADIG_PLL_PLL_VIDEO_SS_STEP(config->ss->step) |
970                                    ANADIG_PLL_PLL_VIDEO_SS_STOP(config->ss->stop) | ANADIG_PLL_PLL_VIDEO_SS_ENABLE_MASK;
971     }
972 
973     ANADIG_PLL->PLL_VIDEO_CTRL |= ANADIG_PLL_PLL_VIDEO_CTRL_PLL_VIDEO_CONTROL_MODE_MASK;
974 }
975 
ANATOP_SysPll1Gate(bool enable)976 static void ANATOP_SysPll1Gate(bool enable)
977 {
978     if (!enable)
979     {
980         ANADIG_PLL->SYS_PLL1_CTRL &= ~ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_GATE_MASK;
981     }
982     else
983     {
984         ANADIG_PLL->SYS_PLL1_CTRL |= ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_GATE_MASK;
985     }
986 }
987 
ANATOP_SysPll1Div2En(bool enable)988 static void ANATOP_SysPll1Div2En(bool enable)
989 {
990     if (!enable)
991     {
992         ANADIG_PLL->SYS_PLL1_CTRL &= ~ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_DIV2_MASK;
993     }
994     else
995     {
996         ANADIG_PLL->SYS_PLL1_CTRL |= ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_DIV2_MASK;
997     }
998 }
999 
ANATOP_SysPll1Div5En(bool enable)1000 static void ANATOP_SysPll1Div5En(bool enable)
1001 {
1002     if (!enable)
1003     {
1004         ANADIG_PLL->SYS_PLL1_CTRL &= ~ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_DIV5_MASK;
1005     }
1006     else
1007     {
1008         ANADIG_PLL->SYS_PLL1_CTRL |= ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_DIV5_MASK;
1009     }
1010 }
1011 
ANATOP_SysPll1SwEnClk(bool enable)1012 static void ANATOP_SysPll1SwEnClk(bool enable)
1013 {
1014     if (!enable)
1015     {
1016         ANADIG_PLL->SYS_PLL1_CTRL &= ~ANADIG_PLL_SYS_PLL1_CTRL_ENABLE_CLK_MASK;
1017     }
1018     else
1019     {
1020         ANADIG_PLL->SYS_PLL1_CTRL |= ANADIG_PLL_SYS_PLL1_CTRL_ENABLE_CLK_MASK;
1021     }
1022 }
1023 
ANATOP_SysPll1WaitStable(void)1024 static void ANATOP_SysPll1WaitStable(void)
1025 {
1026     uint32_t reg;
1027     do
1028     {
1029         reg = ANADIG_PLL->SYS_PLL1_CTRL;
1030     } while ((reg & ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_STABLE_MASK) !=
1031              ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_STABLE_MASK); /* wait for PLL locked */
1032 }
1033 
1034 /* 1GPLL */
CLOCK_InitSysPll1(const clock_sys_pll1_config_t * config)1035 void CLOCK_InitSysPll1(const clock_sys_pll1_config_t *config)
1036 {
1037     uint8_t div;
1038     uint32_t numerator, denominator;
1039 
1040     PMU_StaticEnablePllLdo(ANADIG_PMU);
1041     /* bypass pll */
1042     ANATOP_PllBypass(kAI_Itf_1g, true);
1043 
1044     /* sw enable clock */
1045     ANATOP_SysPll1SwEnClk(true);
1046 
1047     denominator = 0x0FFFFFFF;
1048     div         = 41U;
1049     numerator   = 178956970UL;
1050 
1051     /* configure pll */
1052     ANATOP_PllConfigure(kAI_Itf_1g, div, numerator, 0U, denominator,
1053                         (config->ssEnable && (config->ss != NULL)) ? config->ss : NULL);
1054 
1055     /* toggle hold ring off */
1056     ANATOP_PllToggleHoldRingOff(kAI_Itf_1g, 225);
1057 
1058     /* wait pll stable */
1059     ANATOP_SysPll1WaitStable();
1060 
1061     /* enabled clock */
1062     ANATOP_PllEnableClk(kAI_Itf_1g, true);
1063 
1064     /* ungate clock */
1065     ANATOP_SysPll1Gate(false);
1066 
1067     ANATOP_SysPll1Div2En(config->pllDiv2En);
1068     ANATOP_SysPll1Div5En(config->pllDiv5En);
1069 
1070     /* bypass pll */
1071     ANATOP_PllBypass(kAI_Itf_1g, false);
1072 }
1073 
CLOCK_DeinitSysPll1(void)1074 void CLOCK_DeinitSysPll1(void)
1075 {
1076     ANATOP_SysPll1SwEnClk(false);
1077     ANATOP_SysPll1Div2En(false);
1078     ANATOP_SysPll1Div5En(false);
1079     ANATOP_SysPll1Gate(true);
1080     ANATOP_PllEnableClk(kAI_Itf_1g, false);
1081     ANATOP_PllSetPower(kAI_Itf_1g, false);
1082     ANATOP_PllEnableSs(kAI_Itf_1g, false);
1083     ANATOP_PllEnablePllReg(kAI_Itf_1g, false);
1084 }
1085 
CLOCK_GPC_SetSysPll1OutputFreq(const clock_sys_pll1_gpc_config_t * config)1086 void CLOCK_GPC_SetSysPll1OutputFreq(const clock_sys_pll1_gpc_config_t *config)
1087 {
1088     assert(config != NULL);
1089 
1090     ANADIG_PLL->SYS_PLL1_DIV_SELECT  = config->loopDivider;
1091     ANADIG_PLL->SYS_PLL1_NUMERATOR   = config->numerator;
1092     ANADIG_PLL->SYS_PLL1_DENOMINATOR = config->denominator;
1093 
1094     if ((config->ss != NULL) && config->ssEnable)
1095     {
1096         ANADIG_PLL->SYS_PLL1_SS = ANADIG_PLL_SYS_PLL1_SS_STEP(config->ss->step) |
1097                                   ANADIG_PLL_SYS_PLL1_SS_STOP(config->ss->stop) | ANADIG_PLL_SYS_PLL1_SS_ENABLE_MASK;
1098     }
1099 
1100     ANADIG_PLL->SYS_PLL1_CTRL |= ANADIG_PLL_SYS_PLL1_CTRL_SYS_PLL1_CONTROL_MODE_MASK;
1101 }
1102 
CLOCK_OSC_EnableOsc24M(void)1103 void CLOCK_OSC_EnableOsc24M(void)
1104 {
1105     if (0UL == (ANADIG_OSC->OSC_24M_CTRL & ANADIG_OSC_OSC_24M_CTRL_OSC_EN_MASK))
1106     {
1107         ANADIG_OSC->OSC_24M_CTRL |= ANADIG_OSC_OSC_24M_CTRL_OSC_EN_MASK;
1108         while (ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK !=
1109                (ANADIG_OSC->OSC_24M_CTRL & ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK))
1110         {
1111         }
1112     }
1113 }
1114 
1115 /*!
1116  * brief Set the work mode of 24MHz crystal oscillator, the available modes are high gian mode, low power mode, and
1117  * bypass mode.
1118  *
1119  * param workMode The work mode of 24MHz crystal oscillator, please refer to @ref clock_24MOsc_mode_t for details.
1120  */
CLOCK_OSC_SetOsc24MWorkMode(clock_24MOsc_mode_t workMode)1121 void CLOCK_OSC_SetOsc24MWorkMode(clock_24MOsc_mode_t workMode)
1122 {
1123     uint32_t tmp32;
1124 
1125     tmp32 = ANADIG_OSC->OSC_24M_CTRL;
1126     tmp32 &= ~(ANADIG_OSC_OSC_24M_CTRL_LP_EN_MASK | ANADIG_OSC_OSC_24M_CTRL_BYPASS_EN_MASK);
1127     tmp32 |= (((uint32_t)workMode << ANADIG_OSC_OSC_24M_CTRL_BYPASS_EN_SHIFT) &
1128               (ANADIG_OSC_OSC_24M_CTRL_LP_EN_MASK | ANADIG_OSC_OSC_24M_CTRL_BYPASS_EN_MASK));
1129     ANADIG_OSC->OSC_24M_CTRL = tmp32;
1130 }
1131 
1132 /*!
1133  * brief Configure the 16MHz oscillator.
1134  *
1135  * param source Used to select the source for 16MHz RC oscillator, please refer to clock_16MOsc_source_t.
1136  * param enablePowerSave Enable/disable power save mode function at 16MHz OSC.
1137  *          - \b true Enable power save mode function at 16MHz osc.
1138  *          - \b false Disable power save mode function at 16MHz osc.
1139  * param enableClockOut Enable/Disable clock output for 16MHz RCOSC.
1140  *          - \b true Enable clock output for 16MHz RCOSC.
1141  *          - \b false Disable clock output for 16MHz RCOSC.
1142  */
CLOCK_OSC_SetOsc16MConfig(clock_16MOsc_source_t source,bool enablePowerSave,bool enableClockOut)1143 void CLOCK_OSC_SetOsc16MConfig(clock_16MOsc_source_t source, bool enablePowerSave, bool enableClockOut)
1144 {
1145     uint32_t tmp32;
1146 
1147     tmp32 = ANADIG_OSC->OSC_16M_CTRL;
1148     tmp32 &= ~(ANADIG_OSC_OSC_16M_CTRL_EN_IRC4M16M_MASK | ANADIG_OSC_OSC_16M_CTRL_EN_POWER_SAVE_MASK |
1149                ANADIG_OSC_OSC_16M_CTRL_SOURCE_SEL_16M_MASK);
1150     tmp32 |= ANADIG_OSC_OSC_16M_CTRL_EN_IRC4M16M(enableClockOut) |
1151              ANADIG_OSC_OSC_16M_CTRL_EN_POWER_SAVE(enablePowerSave) | ANADIG_OSC_OSC_16M_CTRL_SOURCE_SEL_16M(source);
1152     ANADIG_OSC->OSC_16M_CTRL = tmp32;
1153 }
1154 
1155 /*!
1156  * brief Set the divide value for ref_clk to generate slow clock.
1157  *
1158  * note slow_clk = ref_clk / (divValue + 1), and the recommand divide value is 24.
1159  *
1160  * param divValue The divide value to be set, the available range is 0~63.
1161  */
CLOCK_OSC_SetOscRc400MRefClkDiv(uint8_t divValue)1162 void CLOCK_OSC_SetOscRc400MRefClkDiv(uint8_t divValue)
1163 {
1164     uint32_t tmp32;
1165 
1166     tmp32 = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_CTRL0);
1167     tmp32 = ((tmp32 & ~AI_RCOSC400M_CTRL0_REF_CLK_DIV_MASK) | AI_RCOSC400M_CTRL0_REF_CLK_DIV(divValue));
1168     ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL0, tmp32);
1169 }
1170 
1171 /*!
1172  * brief Set the target count for the fast clock.
1173  *
1174  * param targetCount The desired target for the fast clock, should be the number of clock cycles of the fast_clk per
1175  * divided ref_clk.
1176  */
CLOCK_OSC_SetOscRc400MFastClkCount(uint16_t targetCount)1177 void CLOCK_OSC_SetOscRc400MFastClkCount(uint16_t targetCount)
1178 {
1179     uint32_t tmp32;
1180 
1181     tmp32 = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_CTRL1);
1182     tmp32 = ((tmp32 & ~AI_RCOSC400M_CTRL1_TARGET_COUNT_MASK) | AI_RCOSC400M_CTRL1_TARGET_COUNT(targetCount));
1183     ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL1, tmp32);
1184 }
1185 
1186 /*!
1187  * brief Set the negative and positive hysteresis value for the tuned clock.
1188  *
1189  * note The hysteresis value should be set after the clock is tuned.
1190  *
1191  * param negHysteresis The negative hysteresis value for the turned clock, this value in number of clock cycles of the
1192  * fast clock
1193  * param posHysteresis The positive hysteresis value for the turned clock, this value in number of clock cycles of the
1194  * fast clock
1195  */
CLOCK_OSC_SetOscRc400MHysteresisValue(uint8_t negHysteresis,uint8_t posHysteresis)1196 void CLOCK_OSC_SetOscRc400MHysteresisValue(uint8_t negHysteresis, uint8_t posHysteresis)
1197 {
1198     uint32_t tmp32;
1199 
1200     tmp32 = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_CTRL1);
1201     tmp32 = ((tmp32 & ~(AI_RCOSC400M_CTRL1_HYST_PLUS_MASK | AI_RCOSC400M_CTRL1_HYST_MINUS_MASK)) |
1202              (AI_RCOSC400M_CTRL1_HYST_PLUS(posHysteresis) | AI_RCOSC400M_CTRL1_HYST_MINUS(negHysteresis)));
1203     ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL1, tmp32);
1204 }
1205 
1206 /*!
1207  * brief Bypass/un-bypass the tune logic
1208  *
1209  * param enableBypass Used to control whether to bypass the turn logic.
1210  *        - \b true Bypass the tune logic and use the programmed oscillator frequency to run the oscillator.
1211  *                  Function CLOCK_OSC_SetOscRc400MTuneValue() can be used to set oscillator frequency.
1212  *        - \b false Use the output of tune logic to run the oscillator.
1213  */
CLOCK_OSC_BypassOscRc400MTuneLogic(bool enableBypass)1214 void CLOCK_OSC_BypassOscRc400MTuneLogic(bool enableBypass)
1215 {
1216     if (enableBypass)
1217     {
1218         ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL2_SET, AI_RCOSC400M_CTRL2_TUNE_BYP_MASK);
1219     }
1220     else
1221     {
1222         ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL2_CLR, AI_RCOSC400M_CTRL2_TUNE_BYP_MASK);
1223     }
1224 }
1225 
1226 /*!
1227  * brief Start/Stop the tune logic.
1228  *
1229  * param enable Used to start or stop the tune logic.
1230  *          - \b true Start tuning
1231  *          - \b false Stop tuning and reset the tuning logic.
1232  */
CLOCK_OSC_EnableOscRc400MTuneLogic(bool enable)1233 void CLOCK_OSC_EnableOscRc400MTuneLogic(bool enable)
1234 {
1235     if (enable)
1236     {
1237         ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL2_SET, AI_RCOSC400M_CTRL2_TUNE_START_MASK);
1238     }
1239     else
1240     {
1241         ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL2_CLR, AI_RCOSC400M_CTRL2_TUNE_START_MASK);
1242     }
1243 }
1244 
1245 /*!
1246  * brief Freeze/Unfreeze the tuning value.
1247  *
1248  * param enableFreeze Used to control whether to freeze the tune value.
1249  *          - \b true Freeze the tune at the current tuned value and the oscillator runs at tje frozen tune value.
1250  *          - \b false Unfreezes and continues the tune operation.
1251  */
CLOCK_OSC_FreezeOscRc400MTuneValue(bool enableFreeze)1252 void CLOCK_OSC_FreezeOscRc400MTuneValue(bool enableFreeze)
1253 {
1254     if (enableFreeze)
1255     {
1256         ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL2_SET, AI_RCOSC400M_CTRL2_TUNE_EN_MASK);
1257     }
1258     else
1259     {
1260         ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL2_CLR, AI_RCOSC400M_CTRL2_TUNE_EN_MASK);
1261     }
1262 }
1263 
1264 /*!
1265  * @brief Set the 400MHz RC oscillator tune value when the tune logic is disabled.
1266  *
1267  * @param tuneValue The tune value to determine the frequency of Oscillator.
1268  */
CLOCK_OSC_SetOscRc400MTuneValue(uint8_t tuneValue)1269 void CLOCK_OSC_SetOscRc400MTuneValue(uint8_t tuneValue)
1270 {
1271     uint32_t tmp32;
1272 
1273     tmp32 = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_CTRL2);
1274     tmp32 &= ~AI_RCOSC400M_CTRL2_OSC_TUNE_VAL_MASK;
1275     tmp32 |= AI_RCOSC400M_CTRL2_OSC_TUNE_VAL(tuneValue);
1276     ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL2, tmp32);
1277 }
1278 
1279 /*!
1280  * brief Set the behavior of the 1MHz output clock, such as disable the 1MHz clock output,
1281  * enable the free-running 1MHz clock output, enable the locked 1MHz clock output.
1282  *
1283  * note The 1MHz clock is divided from 400M RC Oscillator.
1284  *
1285  * param behavior The behavior of 1MHz output clock, please refer to clock_1MHzOut_behavior_t for details.
1286  */
CLOCK_OSC_Set1MHzOutputBehavior(clock_1MHzOut_behavior_t behavior)1287 void CLOCK_OSC_Set1MHzOutputBehavior(clock_1MHzOut_behavior_t behavior)
1288 {
1289     uint32_t tmp32;
1290 
1291     tmp32 = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_CTRL3);
1292     tmp32 &= ~(AI_RCOSC400M_CTRL3_EN_1M_CLK_MASK | AI_RCOSC400M_CTRL3_MUX_1M_CLK_MASK);
1293 
1294     if (behavior == kCLOCK_1MHzOutDisable)
1295     {
1296         tmp32 |= AI_RCOSC400M_CTRL3_EN_1M_CLK_MASK;
1297     }
1298     else
1299     {
1300         if (behavior == kCLOCK_1MHzOutEnableLocked1Mhz)
1301         {
1302             tmp32 |= AI_RCOSC400M_CTRL3_MUX_1M_CLK_MASK;
1303         }
1304     }
1305     ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL3, tmp32);
1306 }
1307 
1308 /*!
1309  * brief Set the count for the locked 1MHz clock out.
1310  *
1311  * param count Used to set the desired target for the locked 1MHz clock out, the value in number of clock cycles of the
1312  * osc_out_400M per divided ref_clk.
1313  */
CLOCK_OSC_SetLocked1MHzCount(uint16_t count)1314 void CLOCK_OSC_SetLocked1MHzCount(uint16_t count)
1315 {
1316     uint32_t tmp32;
1317     uint16_t targetCount;
1318     uint16_t hystMinus;
1319     uint16_t diffCount;
1320 
1321     tmp32       = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_CTRL1);
1322     targetCount = (uint16_t)((tmp32 & AI_RCOSC400M_CTRL1_TARGET_COUNT_MASK) >> AI_RCOSC400M_CTRL1_TARGET_COUNT_SHIFT);
1323     hystMinus   = (uint16_t)((tmp32 & AI_RCOSC400M_CTRL1_HYST_MINUS_MASK) >> AI_RCOSC400M_CTRL1_HYST_MINUS_SHIFT);
1324     diffCount   = targetCount - hystMinus - count;
1325 
1326     /* The count for the locked 1MHz clock should be 4 to 8 counts less than CTRL[TARGET_COUNT] - CTRL1[HYST_MINUS]. */
1327     if ((diffCount >= 4U) && (diffCount <= 8U))
1328     {
1329         tmp32 = (tmp32 & ~AI_RCOSC400M_CTRL3_COUNT_1M_CLK_MASK) | AI_RCOSC400M_CTRL3_COUNT_1M_CLK(count);
1330         ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL3, tmp32);
1331     }
1332 }
1333 
1334 /*!
1335  * brief Check the error flag for locked 1MHz clock out.
1336  *
1337  * return The error flag for locked 1MHz clock out.
1338  *      - \b true The count value has been reached within one diviced ref clock period
1339  *      - \b false No effect.
1340  */
CLOCK_OSC_CheckLocked1MHzErrorFlag(void)1341 bool CLOCK_OSC_CheckLocked1MHzErrorFlag(void)
1342 {
1343     uint32_t tmp32;
1344 
1345     tmp32 = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_STAT0);
1346 
1347     return ((tmp32 & AI_RCOSC400M_STAT0_CLK1M_ERR_MASK) == AI_RCOSC400M_STAT0_CLK1M_ERR_MASK);
1348 }
1349 
1350 /*!
1351  * brief Clear the error flag for locked 1MHz clock out.
1352  */
CLOCK_OSC_ClearLocked1MHzErrorFlag(void)1353 void CLOCK_OSC_ClearLocked1MHzErrorFlag(void)
1354 {
1355     ANATOP_AI_Write(kAI_Itf_400m, kAI_RCOSC400M_CTRL3_SET, AI_RCOSC400M_CTRL3_CLR_ERR_MASK);
1356 }
1357 
1358 /*!
1359  * brief Get current count for the fast clock during the tune process.
1360  *
1361  * return The current count for the fast clock.
1362  */
CLOCK_OSC_GetCurrentOscRc400MFastClockCount(void)1363 uint16_t CLOCK_OSC_GetCurrentOscRc400MFastClockCount(void)
1364 {
1365     uint32_t tmp32;
1366 
1367     tmp32 = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_STAT1);
1368 
1369     return (uint16_t)((tmp32 & AI_RCOSC400M_STAT1_CURR_COUNT_VAL_MASK) >> AI_RCOSC400M_STAT1_CURR_COUNT_VAL_SHIFT);
1370 }
1371 
1372 /*!
1373  * brief Get current tune value used by oscillator during tune process.
1374  *
1375  * return The current tune value.
1376  */
CLOCK_OSC_GetCurrentOscRc400MTuneValue(void)1377 uint8_t CLOCK_OSC_GetCurrentOscRc400MTuneValue(void)
1378 {
1379     uint32_t tmp32;
1380 
1381     tmp32 = ANATOP_AI_Read(kAI_Itf_400m, kAI_RCOSC400M_STAT2);
1382 
1383     return (uint8_t)((tmp32 & AI_RCOSC400M_STAT2_CURR_OSC_TUNE_VAL_MASK) >> AI_RCOSC400M_STAT2_CURR_OSC_TUNE_VAL_SHIFT);
1384 }
1385 
1386 #ifndef GET_FREQ_FROM_OBS
CLOCK_GetAvPllFreq(clock_pll_t pll)1387 static uint32_t CLOCK_GetAvPllFreq(clock_pll_t pll)
1388 {
1389     uint32_t freq = 0;
1390     uint32_t div;
1391     uint32_t post_div;
1392     double tmpDouble;
1393     double denom;
1394     double numer;
1395 
1396     assert((pll == kCLOCK_PllAudio) || (pll == kCLOCK_PllVideo));
1397 
1398     div      = ANATOP_AI_Read(pll == kCLOCK_PllAudio ? kAI_Itf_Audio : kAI_Itf_Video, PLL_AI_CTRL0_REG);
1399     post_div = (div & (0xE000000UL)) >> 25UL;
1400     div &= 0x7fUL;
1401     denom = (double)ANATOP_AI_Read(pll == kCLOCK_PllAudio ? kAI_Itf_Audio : kAI_Itf_Video, PLL_AI_CTRL3_REG);
1402     numer = (double)ANATOP_AI_Read(pll == kCLOCK_PllAudio ? kAI_Itf_Audio : kAI_Itf_Video, PLL_AI_CTRL2_REG);
1403 
1404     tmpDouble = ((double)XTAL_FREQ * ((double)div + (numer / denom)) / (double)(uint32_t)(1UL << post_div));
1405     freq      = (uint32_t)tmpDouble;
1406 
1407     return freq;
1408 }
1409 #endif
1410 
CLOCK_GetPllFreq(clock_pll_t pll)1411 uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
1412 {
1413     uint32_t freq = 0;
1414 #ifndef GET_FREQ_FROM_OBS
1415     uint32_t divSelect, postDiv;
1416 #endif
1417 
1418     switch (pll)
1419     {
1420         case kCLOCK_PllArm:
1421 #ifndef GET_FREQ_FROM_OBS
1422             divSelect = (ANADIG_PLL->ARM_PLL_CTRL & ANADIG_PLL_ARM_PLL_CTRL_DIV_SELECT_MASK) >>
1423                         ANADIG_PLL_ARM_PLL_CTRL_DIV_SELECT_SHIFT;
1424             postDiv = (ANADIG_PLL->ARM_PLL_CTRL & ANADIG_PLL_ARM_PLL_CTRL_POST_DIV_SEL_MASK) >>
1425                       ANADIG_PLL_ARM_PLL_CTRL_POST_DIV_SEL_SHIFT;
1426             postDiv = (1UL << (postDiv + 1UL));
1427             freq    = XTAL_FREQ / (2UL * postDiv);
1428             freq *= divSelect;
1429 #else
1430             freq = CLOCK_GetFreqFromObs(CCM_OBS_ARM_PLL_OUT);
1431 #endif
1432             break;
1433         case kCLOCK_PllSys1:
1434 #ifndef GET_FREQ_FROM_OBS
1435             freq = SYS_PLL1_FREQ;
1436 #else
1437             freq = CLOCK_GetFreqFromObs(CCM_OBS_SYS_PLL1_OUT);
1438 #endif
1439             break;
1440         case kCLOCK_PllSys2:
1441 #ifndef GET_FREQ_FROM_OBS
1442             freq = SYS_PLL2_FREQ;
1443 #else
1444             freq = CLOCK_GetFreqFromObs(CCM_OBS_SYS_PLL2_OUT);
1445 #endif
1446             break;
1447         case kCLOCK_PllSys3:
1448 #ifndef GET_FREQ_FROM_OBS
1449             freq = SYS_PLL3_FREQ;
1450 #else
1451             freq = CLOCK_GetFreqFromObs(CCM_OBS_SYS_PLL3_OUT);
1452 #endif
1453             break;
1454         case kCLOCK_PllAudio:
1455 #ifndef GET_FREQ_FROM_OBS
1456             freq = CLOCK_GetAvPllFreq(kCLOCK_PllAudio);
1457 #else
1458             freq = CLOCK_GetFreqFromObs(CCM_OBS_PLL_AUDIO_OUT);
1459 #endif
1460             break;
1461         case kCLOCK_PllVideo:
1462 #ifndef GET_FREQ_FROM_OBS
1463             freq = CLOCK_GetAvPllFreq(kCLOCK_PllVideo);
1464 #else
1465             freq = CLOCK_GetFreqFromObs(CCM_OBS_PLL_VIDEO_OUT);
1466 #endif
1467             break;
1468         default:
1469             /* Wrong input parameter pll. */
1470             assert(false);
1471             break;
1472     }
1473     assert(freq != 0UL);
1474     return freq;
1475 }
1476 
CLOCK_GetFreq(clock_name_t name)1477 uint32_t CLOCK_GetFreq(clock_name_t name)
1478 {
1479     uint32_t freq = 0;
1480 
1481     assert(name != kCLOCK_Reserved);
1482 
1483     switch (name)
1484     {
1485         case kCLOCK_OscRc16M:
1486 #ifndef GET_FREQ_FROM_OBS
1487             freq = 16000000U;
1488 #else
1489             freq = CLOCK_GetFreqFromObs(CCM_OBS_OSC_RC_16M);
1490 #endif
1491             break;
1492         case kCLOCK_OscRc48M:
1493 #ifndef GET_FREQ_FROM_OBS
1494             freq = 48000000U;
1495 #else
1496             freq = CLOCK_GetFreqFromObs(CCM_OBS_OSC_RC_48M);
1497 #endif
1498             break;
1499         case kCLOCK_OscRc48MDiv2:
1500 #ifndef GET_FREQ_FROM_OBS
1501             freq = 24000000U;
1502 #else
1503             freq = CLOCK_GetFreqFromObs(CCM_OBS_OSC_RC_48M_DIV2);
1504 #endif
1505             break;
1506         case kCLOCK_OscRc400M:
1507 #ifndef GET_FREQ_FROM_OBS
1508             freq = 400000000U;
1509 #else
1510             freq = CLOCK_GetFreqFromObs(CCM_OBS_OSC_RC_400M);
1511 #endif
1512             break;
1513         case kCLOCK_Osc24MOut:
1514         case kCLOCK_Osc24M:
1515 #ifndef GET_FREQ_FROM_OBS
1516             freq = 24000000U;
1517 #else
1518             freq = CLOCK_GetFreqFromObs(CCM_OBS_OSC_24M_OUT);
1519 #endif
1520             break;
1521         case kCLOCK_ArmPllOut:
1522         case kCLOCK_ArmPll:
1523             freq = CLOCK_GetPllFreq(kCLOCK_PllArm);
1524             break;
1525         case kCLOCK_SysPll2:
1526         case kCLOCK_SysPll2Out:
1527             freq = CLOCK_GetPllFreq(kCLOCK_PllSys2);
1528             break;
1529         case kCLOCK_SysPll2Pfd0:
1530             freq = CLOCK_GetPfdFreq(kCLOCK_PllSys2, kCLOCK_Pfd0);
1531             break;
1532         case kCLOCK_SysPll2Pfd1:
1533             freq = CLOCK_GetPfdFreq(kCLOCK_PllSys2, kCLOCK_Pfd1);
1534             break;
1535         case kCLOCK_SysPll2Pfd2:
1536             freq = CLOCK_GetPfdFreq(kCLOCK_PllSys2, kCLOCK_Pfd2);
1537             break;
1538         case kCLOCK_SysPll2Pfd3:
1539             freq = CLOCK_GetPfdFreq(kCLOCK_PllSys2, kCLOCK_Pfd3);
1540             break;
1541         case kCLOCK_SysPll3Out:
1542         case kCLOCK_SysPll3:
1543             freq = CLOCK_GetPllFreq(kCLOCK_PllSys3);
1544             break;
1545         case kCLOCK_SysPll3Div2:
1546             freq = (CLOCK_GetPllFreq(kCLOCK_PllSys3) / 2UL);
1547             break;
1548         case kCLOCK_SysPll3Pfd0:
1549             freq = CLOCK_GetPfdFreq(kCLOCK_PllSys3, kCLOCK_Pfd0);
1550             break;
1551         case kCLOCK_SysPll3Pfd1:
1552             freq = CLOCK_GetPfdFreq(kCLOCK_PllSys3, kCLOCK_Pfd1);
1553             break;
1554         case kCLOCK_SysPll3Pfd2:
1555             freq = CLOCK_GetPfdFreq(kCLOCK_PllSys3, kCLOCK_Pfd2);
1556             break;
1557         case kCLOCK_SysPll3Pfd3:
1558             freq = CLOCK_GetPfdFreq(kCLOCK_PllSys3, kCLOCK_Pfd3);
1559             break;
1560         case kCLOCK_SysPll1:
1561         case kCLOCK_SysPll1Out:
1562             freq = CLOCK_GetPllFreq(kCLOCK_PllSys1);
1563             break;
1564         case kCLOCK_SysPll1Div2:
1565             freq = CLOCK_GetPllFreq(kCLOCK_PllSys1) / 2UL;
1566             break;
1567         case kCLOCK_SysPll1Div5:
1568             freq = CLOCK_GetPllFreq(kCLOCK_PllSys1) / 5UL;
1569             break;
1570         case kCLOCK_AudioPll:
1571         case kCLOCK_AudioPllOut:
1572             freq = CLOCK_GetPllFreq(kCLOCK_PllAudio);
1573             break;
1574         case kCLOCK_VideoPll:
1575         case kCLOCK_VideoPllOut:
1576             freq = CLOCK_GetPllFreq(kCLOCK_PllVideo);
1577             break;
1578         case kCLOCK_CpuClk:
1579         case kCLOCK_CoreSysClk:
1580             freq = CLOCK_GetCpuClkFreq();
1581             break;
1582         default:
1583             /* Wrong input parameter name. */
1584             assert(false);
1585             break;
1586     }
1587     assert(freq != 0UL);
1588     return freq;
1589 }
1590 
CLOCK_SetGroupConfig(clock_group_t group,const clock_group_config_t * config)1591 void CLOCK_SetGroupConfig(clock_group_t group, const clock_group_config_t *config)
1592 {
1593     assert(group < kCLOCK_Group_Last);
1594 
1595     CCM->CLOCK_GROUP[group].CONTROL = ((config->clockOff ? CCM_CLOCK_GROUP_CONTROL_OFF_MASK : 0UL) |
1596                                        ((uint32_t)config->resetDiv << CCM_CLOCK_GROUP_CONTROL_RSTDIV_SHIFT) |
1597                                        (config->div0 << CCM_CLOCK_GROUP_CONTROL_DIV0_SHIFT));
1598 }
1599 
CLOCK_OSC_TrimOscRc400M(bool enable,bool bypass,uint16_t trim)1600 void CLOCK_OSC_TrimOscRc400M(bool enable, bool bypass, uint16_t trim)
1601 {
1602     if (enable)
1603     {
1604         ANADIG_MISC->VDDLPSR_AI400M_CTRL  = 0x20UL;
1605         ANADIG_MISC->VDDLPSR_AI400M_WDATA = ((uint32_t)bypass << 10UL) | ((uint32_t)trim << 24UL);
1606         ANADIG_MISC->VDDLPSR_AI400M_CTRL |= 0x100UL;
1607         SDK_DelayAtLeastUs(1, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1608         ANADIG_MISC->VDDLPSR_AI400M_CTRL &= ~0x100UL;
1609     }
1610 }
1611 
CLOCK_OSC_EnableOscRc400M(void)1612 void CLOCK_OSC_EnableOscRc400M(void)
1613 {
1614     ANADIG_OSC->OSC_400M_CTRL1 &= ~ANADIG_OSC_OSC_400M_CTRL1_PWD_MASK;
1615     ANADIG_OSC->OSC_400M_CTRL2 |= ANADIG_OSC_OSC_400M_CTRL2_ENABLE_CLK_MASK;
1616 }
1617 
CLOCK_GetFreqFromObs(uint32_t obsSigIndex,uint32_t obsIndex)1618 uint32_t CLOCK_GetFreqFromObs(uint32_t obsSigIndex, uint32_t obsIndex)
1619 {
1620     CCM_OBS->OBSERVE[obsIndex].CONTROL     = CCM_OBS_OBSERVE_CONTROL_OFF_MASK;   /* turn off detect */
1621     CCM_OBS->OBSERVE[obsIndex].CONTROL_SET = CCM_OBS_OBSERVE_CONTROL_RESET_MASK; /* reset slice */
1622     CCM_OBS->OBSERVE[obsIndex].CONTROL_CLR = CCM_OBS_OBSERVE_CONTROL_RAW_MASK;   /* select raw obsSigIndex */
1623     CCM_OBS->OBSERVE[obsIndex].CONTROL &= ~CCM_OBS_OBSERVE_CONTROL_SELECT_MASK;  /* Select observed obsSigIndex */
1624     CCM_OBS->OBSERVE[obsIndex].CONTROL |= CCM_OBS_OBSERVE_CONTROL_SELECT(obsSigIndex) |
1625                                           CCM_OBS_OBSERVE_CONTROL_DIVIDE(CCM_OBS_DIV); /* turn on detection */
1626     CCM_OBS->OBSERVE[obsIndex].CONTROL_CLR =
1627         CCM_OBS_OBSERVE_CONTROL_RESET_MASK | CCM_OBS_OBSERVE_CONTROL_OFF_MASK; /* unreset and turn on detect */
1628 
1629     while (CCM_OBS->OBSERVE[obsIndex].FREQUENCY_CURRENT == 0UL)
1630     {
1631     }
1632 
1633     return (CCM_OBS->OBSERVE[obsIndex].FREQUENCY_CURRENT * ((uint32_t)CCM_OBS_DIV + 1UL));
1634 }
1635 
1636 /*! brief Enable USB HS clock.
1637  *
1638  * This function only enables the access to USB HS prepheral, upper layer
1639  * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
1640  * clock to use USB HS.
1641  *
1642  * param src  USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused.
1643  * param freq USB HS does not care about the clock source, so this parameter is ignored.
1644  * retval true The clock is set successfully.
1645  * retval false The clock source is invalid to get proper USB HS clock.
1646  */
CLOCK_EnableUsbhs0Clock(clock_usb_src_t src,uint32_t freq)1647 bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq)
1648 {
1649     return true;
1650 }
1651 /*! brief Enable USB HS PHY PLL clock.
1652  *
1653  * This function enables the internal 480MHz USB PHY PLL clock.
1654  *
1655  * param src  USB HS PHY PLL clock source.
1656  * param freq The frequency specified by src.
1657  * retval true The clock is set successfully.
1658  * retval false The clock source is invalid to get proper USB HS clock.
1659  */
CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src,uint32_t freq)1660 bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
1661 {
1662     uint32_t phyPllDiv  = 0U;
1663     uint16_t multiplier = 0U;
1664     bool err            = false;
1665     CLOCK_EnableClock(kCLOCK_Usb);
1666 
1667     USBPHY1->CTRL_CLR = USBPHY_CTRL_SFTRST_MASK;
1668 
1669     USBPHY1->PLL_SIC_SET = (USBPHY_PLL_SIC_PLL_POWER(1) | USBPHY_PLL_SIC_PLL_REG_ENABLE_MASK);
1670     if ((480000000UL % freq) != 0UL)
1671     {
1672         return false;
1673     }
1674     multiplier = (uint16_t)(480000000UL / freq);
1675 
1676     switch (multiplier)
1677     {
1678         case 13:
1679         {
1680             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(0U);
1681             break;
1682         }
1683         case 15:
1684         {
1685             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(1U);
1686             break;
1687         }
1688         case 16:
1689         {
1690             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(2U);
1691             break;
1692         }
1693         case 20:
1694         {
1695             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(3U);
1696             break;
1697         }
1698         case 22:
1699         {
1700             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(4U);
1701             break;
1702         }
1703         case 25:
1704         {
1705             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(5U);
1706             break;
1707         }
1708         case 30:
1709         {
1710             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(6U);
1711             break;
1712         }
1713         case 240:
1714         {
1715             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(7U);
1716             break;
1717         }
1718         default:
1719         {
1720             err = true;
1721             break;
1722         }
1723     }
1724 
1725     if (err)
1726     {
1727         return false;
1728     }
1729 
1730     USBPHY1->PLL_SIC = (USBPHY1->PLL_SIC & ~(USBPHY_PLL_SIC_PLL_DIV_SEL_MASK)) | phyPllDiv;
1731 
1732     USBPHY1->PLL_SIC_CLR = USBPHY_PLL_SIC_PLL_BYPASS_MASK;
1733     USBPHY1->PLL_SIC_SET = (USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK);
1734 
1735     USBPHY1->CTRL_CLR = USBPHY_CTRL_CLR_CLKGATE_MASK;
1736 
1737     while (0UL == (USBPHY1->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK))
1738     {
1739     }
1740     return true;
1741 }
1742 /*! brief Enable USB HS clock.
1743  *
1744  * This function only enables the access to USB HS prepheral, upper layer
1745  * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
1746  * clock to use USB HS.
1747  *
1748  * param src  USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused.
1749  * param freq USB HS does not care about the clock source, so this parameter is ignored.
1750  * retval true The clock is set successfully.
1751  * retval false The clock source is invalid to get proper USB HS clock.
1752  */
1753 /*! brief Disable USB HS PHY PLL clock.
1754  *
1755  * This function disables USB HS PHY PLL clock.
1756  */
CLOCK_DisableUsbhs0PhyPllClock(void)1757 void CLOCK_DisableUsbhs0PhyPllClock(void)
1758 {
1759     USBPHY1->PLL_SIC_CLR = (USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK);
1760     USBPHY1->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */
1761 }
CLOCK_EnableUsbhs1Clock(clock_usb_src_t src,uint32_t freq)1762 bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq)
1763 {
1764     return true;
1765 }
CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src,uint32_t freq)1766 bool CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
1767 {
1768     uint32_t phyPllDiv  = 0U;
1769     uint16_t multiplier = 0U;
1770     bool err            = false;
1771     CLOCK_EnableClock(kCLOCK_Usb);
1772 
1773     USBPHY2->CTRL_CLR = USBPHY_CTRL_SFTRST_MASK;
1774 
1775     USBPHY2->PLL_SIC_SET = (USBPHY_PLL_SIC_PLL_POWER(1) | USBPHY_PLL_SIC_PLL_REG_ENABLE_MASK);
1776     if ((480000000UL % freq) != 0UL)
1777     {
1778         return false;
1779     }
1780     multiplier = (uint16_t)(uint32_t)(480000000UL / freq);
1781 
1782     switch (multiplier)
1783     {
1784         case 13:
1785         {
1786             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(0U);
1787             break;
1788         }
1789         case 15:
1790         {
1791             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(1U);
1792             break;
1793         }
1794         case 16:
1795         {
1796             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(2U);
1797             break;
1798         }
1799         case 20:
1800         {
1801             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(3U);
1802             break;
1803         }
1804         case 22:
1805         {
1806             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(4U);
1807             break;
1808         }
1809         case 25:
1810         {
1811             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(5U);
1812             break;
1813         }
1814         case 30:
1815         {
1816             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(6U);
1817             break;
1818         }
1819         case 240:
1820         {
1821             phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(7U);
1822             break;
1823         }
1824         default:
1825         {
1826             err = true;
1827             break;
1828         }
1829     }
1830 
1831     if (err)
1832     {
1833         return false;
1834     }
1835     USBPHY2->PLL_SIC = (USBPHY2->PLL_SIC & ~(USBPHY_PLL_SIC_PLL_DIV_SEL_MASK)) | phyPllDiv;
1836 
1837     USBPHY2->PLL_SIC_CLR = USBPHY_PLL_SIC_PLL_BYPASS_MASK;
1838     USBPHY2->PLL_SIC_SET = (USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK);
1839 
1840     USBPHY2->CTRL_CLR = USBPHY_CTRL_CLR_CLKGATE_MASK;
1841 
1842     while (0UL == (USBPHY2->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK))
1843     {
1844     }
1845     return true;
1846 }
1847 /*! brief Disable USB HS PHY PLL clock.
1848  *
1849  * This function disables USB HS PHY PLL clock.
1850  */
CLOCK_DisableUsbhs1PhyPllClock(void)1851 void CLOCK_DisableUsbhs1PhyPllClock(void)
1852 {
1853     USBPHY2->PLL_SIC_CLR = (USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK);
1854     USBPHY2->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */
1855 }
1856 
CLOCK_OSCPLL_ControlBySetPointMode(clock_name_t name,uint16_t spValue,uint16_t stbyValue)1857 void CLOCK_OSCPLL_ControlBySetPointMode(clock_name_t name, uint16_t spValue, uint16_t stbyValue)
1858 {
1859     /* Set control mode to unassigned mode. */
1860     CCM->OSCPLL[name].AUTHEN &=
1861         ~(CCM_OSCPLL_AUTHEN_CPULPM_MASK | CCM_OSCPLL_AUTHEN_DOMAIN_MODE_MASK | CCM_OSCPLL_AUTHEN_SETPOINT_MODE_MASK);
1862     /* Change SetPoint value in unassigned mode. */
1863     CCM->OSCPLL[name].SETPOINT = CCM_OSCPLL_SETPOINT_STANDBY(stbyValue) | CCM_OSCPLL_SETPOINT_SETPOINT(spValue);
1864     /* Set control mode to SetPoint mode. */
1865     CCM->OSCPLL[name].AUTHEN |= CCM_OSCPLL_AUTHEN_SETPOINT_MODE_MASK;
1866 }
1867 
CLOCK_OSCPLL_ControlByCpuLowPowerMode(clock_name_t name,uint8_t domainId,clock_level_t level0,clock_level_t level1)1868 void CLOCK_OSCPLL_ControlByCpuLowPowerMode(clock_name_t name,
1869                                            uint8_t domainId,
1870                                            clock_level_t level0,
1871                                            clock_level_t level1)
1872 {
1873     /* Set control mode to unassigned mode. */
1874     CCM->OSCPLL[name].AUTHEN &=
1875         ~(CCM_OSCPLL_AUTHEN_SETPOINT_MODE_MASK | CCM_OSCPLL_AUTHEN_DOMAIN_MODE_MASK | CCM_OSCPLL_AUTHEN_CPULPM_MASK);
1876     /* Change clock depend level for each domain in unassigned mode. */
1877     CCM->OSCPLL[name].DOMAINr =
1878         ((((uint32_t)domainId & (1UL << 1UL)) != 0UL) ? CCM_OSCPLL_DOMAIN_LEVEL1(level1) : 0UL) |
1879         (((domainId & (1UL << 0UL)) != 0UL) ? CCM_OSCPLL_DOMAIN_LEVEL0(level0) : 0UL);
1880     /* Set control mode to CPU low power mode and update whitelist. */
1881     CCM->OSCPLL[name].AUTHEN = (CCM->OSCPLL[name].AUTHEN & ~CCM_OSCPLL_AUTHEN_WHITE_LIST_MASK) |
1882                                CCM_OSCPLL_AUTHEN_CPULPM_MASK | CCM_OSCPLL_AUTHEN_WHITE_LIST(domainId);
1883 }
1884 
CLOCK_ROOT_ControlBySetPointMode(clock_root_t name,const clock_root_setpoint_config_t * spTable)1885 void CLOCK_ROOT_ControlBySetPointMode(clock_root_t name, const clock_root_setpoint_config_t *spTable)
1886 {
1887     uint8_t i;
1888 
1889     /* Set control mode to unassigned mode. */
1890     CLOCK_ROOT_ControlByUnassignedMode(name);
1891     /* Change SetPoint value in unassigned mode. */
1892     for (i = 0U; i < 16U; i++)
1893     {
1894         CLOCK_ROOT_ConfigSetPoint(name, i, &spTable[i]);
1895     }
1896     /* Set control mode to SetPoint mode. */
1897     CLOCK_ROOT_EnableSetPointControl(name);
1898 }
1899 
CLOCK_LPCG_ControlBySetPointMode(clock_lpcg_t name,uint16_t spValue,uint16_t stbyValue)1900 void CLOCK_LPCG_ControlBySetPointMode(clock_lpcg_t name, uint16_t spValue, uint16_t stbyValue)
1901 {
1902     /* Set control mode to unassigned mode. */
1903     CCM->LPCG[name].AUTHEN &=
1904         ~(CCM_LPCG_AUTHEN_CPULPM_MASK | CCM_LPCG_AUTHEN_DOMAIN_MODE_MASK | CCM_LPCG_AUTHEN_SETPOINT_MODE_MASK);
1905     /* Change SetPoint value in unassigned mode. */
1906     CCM->LPCG[name].SETPOINT = CCM_LPCG_SETPOINT_STANDBY(stbyValue) | CCM_LPCG_SETPOINT_SETPOINT(spValue);
1907     /* Set control mode to SetPoint mode. */
1908     CCM->LPCG[name].AUTHEN |= CCM_LPCG_AUTHEN_SETPOINT_MODE_MASK;
1909 }
1910 
CLOCK_LPCG_ControlByCpuLowPowerMode(clock_lpcg_t name,uint8_t domainId,clock_level_t level0,clock_level_t level1)1911 void CLOCK_LPCG_ControlByCpuLowPowerMode(clock_lpcg_t name,
1912                                          uint8_t domainId,
1913                                          clock_level_t level0,
1914                                          clock_level_t level1)
1915 {
1916     /* Set control mode to unassigned mode. */
1917     CCM->LPCG[name].AUTHEN &=
1918         ~(CCM_LPCG_AUTHEN_SETPOINT_MODE_MASK | CCM_LPCG_AUTHEN_DOMAIN_MODE_MASK | CCM_LPCG_AUTHEN_CPULPM_MASK);
1919     /* Change clock depend level for each domain in unassigned mode. */
1920     CCM->LPCG[name].DOMAINr = ((((uint32_t)domainId & (1UL << 1UL)) != 0UL) ? CCM_LPCG_DOMAIN_LEVEL1(level1) : 0UL) |
1921                               ((((uint32_t)domainId & (1UL << 0UL)) != 0UL) ? CCM_LPCG_DOMAIN_LEVEL0(level0) : 0UL);
1922     /* Set control mode to CPU low power mode and update whitelist. */
1923     CCM->LPCG[name].AUTHEN = (CCM->LPCG[name].AUTHEN & ~CCM_LPCG_AUTHEN_WHITE_LIST_MASK) | CCM_LPCG_AUTHEN_CPULPM_MASK |
1924                              CCM_LPCG_AUTHEN_WHITE_LIST(domainId);
1925 }
1926