2 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "fsl_mcg_hal.h"
33 /*******************************************************************************
35 ******************************************************************************/
38 /*******************************************************************************
40 ******************************************************************************/
42 /*FUNCTION**********************************************************************
44 * Function Name : CLOCK_HAL_GetFllRefclk
45 * Description : Internal function to find the fll reference clock
46 * This is an internal function to get the fll reference clock. The returned
47 * value will be used for other APIs to calculate teh fll and other clock value.
49 *END**************************************************************************/
50 uint32_t CLOCK_HAL_GetFllRefClk(uint32_t baseAddr
)
55 if (CLOCK_HAL_GetInternalRefSelMode(baseAddr
) == kMcgInternalRefClkSrcExternal
)
57 /* External reference clock is selected */
58 #if FSL_FEATURE_MCG_USE_OSCSEL /* case 1: use oscsel for ffclk */
60 int32_t oscsel
= CLOCK_HAL_GetOscselMode(baseAddr
);
61 if (oscsel
== kMcgOscselOsc
)
63 #if FSL_FEATURE_MCG_HAS_OSC1
64 /* System oscillator 0 drives MCG clock */
65 mcgffclk
= CPU_XTAL0_CLK_HZ
;
67 /* System oscillator 0 drives MCG clock */
68 mcgffclk
= CPU_XTAL_CLK_HZ
;
71 else if (oscsel
== kMcgOscselRtc
)
73 /* RTC 32 kHz oscillator drives MCG clock */
74 mcgffclk
= CPU_XTAL32k_CLK_HZ
;
76 #if FSL_FEATURE_MCG_HAS_IRC_48M /* case 1.1: if IRC 48M exists*/
77 else if (oscsel
== kMcgOscselIrc
)
79 /* IRC 48Mhz oscillator drives MCG clock */
80 mcgffclk
= CPU_INT_IRC_CLK_HZ
;
88 #else /* case 2: use default osc0*/
90 /* System oscillator 0 drives MCG clock */
91 mcgffclk
= CPU_XTAL_CLK_HZ
;
95 divider
= (uint8_t)(1u << CLOCK_HAL_GetFllExternalRefDivider(baseAddr
));
97 /* Calculate the divided FLL reference clock*/
98 mcgffclk
= (mcgffclk
/ divider
);
100 if ((CLOCK_HAL_GetRange0Mode(baseAddr
) != kMcgFreqRangeSelLow
)
101 #if FSL_FEATURE_MCG_USE_OSCSEL /* case 1: use oscsel for ffclk */
102 && (CLOCK_HAL_GetOscselMode(baseAddr
) != kMcgOscselRtc
))
107 /* If high range is enabled, additional 32 divider is active*/
108 mcgffclk
= (mcgffclk
>> kMcgConstant5
);
113 /* The slow internal reference clock is selected */
114 mcgffclk
= CPU_INT_SLOW_CLK_HZ
;
119 /*FUNCTION**********************************************************************
121 * Function Name : CLOCK_HAL_GetFllclk
122 * Description : Get the current mcg fll clock
123 * This function will return the mcgfllclk value in frequency(hz) based on
124 * current mcg configurations and settings. Fll should be properly configured
125 * in order to get the valid value.
127 *END**************************************************************************/
128 uint32_t CLOCK_HAL_GetFllClk(uint32_t baseAddr
)
131 mcg_dmx32_select_t dmx32
;
132 mcg_digital_controlled_osc_range_select_t drstDrs
;
134 mcgfllclk
= CLOCK_HAL_GetFllRefClk(baseAddr
);
136 /* Select correct multiplier to calculate the MCG output clock */
137 dmx32
= CLOCK_HAL_GetDmx32(baseAddr
);
138 drstDrs
= CLOCK_HAL_GetDigitalControlledOscRangeMode(baseAddr
);
142 case kMcgDigitalControlledOscRangeSelLow
: /* Low frequency range */
145 case kMcgDmx32Default
: /* DCO has a default range of 25% */
146 mcgfllclk
*= kMcgConstant640
;
148 case kMcgDmx32Fine
: /* DCO is fine-tuned for max freq 32.768 kHz */
149 mcgfllclk
*= kMcgConstant732
;
155 case kMcgDigitalControlledOscRangeSelMid
: /* Mid frequency range*/
158 case kMcgDmx32Default
: /* DCO has a default range of 25% */
159 mcgfllclk
*= kMcgConstant1280
;
161 case kMcgDmx32Fine
: /* DCO is fine-tuned for max freq 32.768 kHz */
162 mcgfllclk
*= kMcgConstant1464
;
168 case kMcgDigitalControlledOscRangeSelMidHigh
: /* Mid-High frequency range */
171 case kMcgDmx32Default
: /* DCO has a default range of 25% */
172 mcgfllclk
*= kMcgConstant1920
;
174 case kMcgDmx32Fine
: /* DCO is fine-tuned for max freq 32.768 kHz */
175 mcgfllclk
*= kMcgConstant2197
;
181 case kMcgDigitalControlledOscRangeSelHigh
: /* High frequency range */
184 case kMcgDmx32Default
: /* DCO has a default range of 25% */
185 mcgfllclk
*= kMcgConstant2560
;
187 case kMcgDmx32Fine
: /* DCO is fine-tuned for max freq 32.768 kHz */
188 mcgfllclk
*= kMcgConstant2929
;
200 #if FSL_FEATURE_MCG_HAS_PLL
201 /*FUNCTION**********************************************************************
203 * Function Name : CLOCK_HAL_GetPll0clk
204 * Description : Get the current mcg pll/pll0 clock
205 * This function will return the mcgpllclk/mcgpll0 value in frequency(hz) based
206 * on current mcg configurations and settings. PLL/PLL0 should be properly
207 * configured in order to get the valid value.
209 *END**************************************************************************/
210 uint32_t CLOCK_HAL_GetPll0Clk(uint32_t baseAddr
)
215 /* PLL(0) output is selected*/
216 #if FSL_FEATURE_MCG_USE_PLLREFSEL /* case 1 use pllrefsel to select pll*/
218 if (CLOCK_HAL_GetPllRefSel0Mode(baseAddr
) != kMcgPllExternalRefClkSelOsc0
)
220 /* OSC1 clock source used as an external reference clock */
221 mcgpll0clk
= CPU_XTAL1_CLK_HZ
;
225 /* OSC0 clock source used as an external reference clock*/
226 mcgpll0clk
= CPU_XTAL0_CLK_HZ
;
229 #if FSL_FEATURE_MCG_USE_OSCSEL /* case 2: use oscsel for pll */
230 mcg_oscsel_select_t oscsel
= CLOCK_HAL_GetOscselMode(baseAddr
);
231 if (oscsel
== kMcgOscselOsc
) /* case 2.1: OSC0 */
233 /* System oscillator drives MCG clock*/
234 mcgpll0clk
= CPU_XTAL_CLK_HZ
;
236 else if (oscsel
== kMcgOscselRtc
) /* case 2.2: RTC */
238 /* RTC 32 kHz oscillator drives MCG clock*/
239 mcgpll0clk
= CPU_XTAL32k_CLK_HZ
;
241 #if FSL_FEATURE_MCG_HAS_IRC_48M
242 else if (oscsel
== kMcgOscselIrc
) /* case 2.3: IRC 48M */
244 /* IRC 48Mhz oscillator drives MCG clock*/
245 mcgpll0clk
= CPU_INT_IRC_CLK_HZ
;
252 #else /* case 3: use default osc0*/
253 /* System oscillator drives MCG clock*/
254 mcgpll0clk
= CPU_XTAL_CLK_HZ
;
258 divider
= (kMcgConstant1
+ CLOCK_HAL_GetPllExternalRefDivider0(baseAddr
));
260 /* Calculate the PLL reference clock*/
261 mcgpll0clk
/= divider
;
262 divider
= (CLOCK_HAL_GetVoltCtrlOscDivider0(baseAddr
) + FSL_FEATURE_MCG_PLL_VDIV_BASE
);
264 /* Calculate the MCG output clock*/
265 mcgpll0clk
= (mcgpll0clk
* divider
);
271 #if FSL_FEATURE_MCG_HAS_PLL1
272 /*FUNCTION**********************************************************************
274 * Function Name : CLOCK_HAL_GetPll1Clk
275 * Description : Get the current mcg pll1 clock
276 * This function will return the mcgpll1clk value in frequency(hz) based
277 * on current mcg configurations and settings. PLL1 should be properly configured
278 * in order to get the valid value.
280 *END**************************************************************************/
281 uint32_t CLOCK_HAL_GetPll1Clk(uint32_t baseAddr
)
286 if (CLOCK_HAL_GetPllRefSel1Mode(baseAddr
) != kMcgPllExternalRefClkSelOsc0
)
288 /* OSC1 clock source used as an external reference clock*/
289 mcgpll1clk
= CPU_XTAL1_CLK_HZ
;
293 /* OSC0 clock source used as an external reference clock*/
294 mcgpll1clk
= CPU_XTAL0_CLK_HZ
;
297 divider
= (kMcgConstant1
+ CLOCK_HAL_GetPllExternalRefDivider1(baseAddr
));
299 /* Calculate the PLL reference clock*/
300 mcgpll1clk
/= divider
;
301 divider
= (CLOCK_HAL_GetVoltCtrlOscDivider1(baseAddr
) + FSL_FEATURE_MCG_PLL_VDIV_BASE
);
303 /* Calculate the MCG output clock*/
304 mcgpll1clk
= ((mcgpll1clk
* divider
) >> kMcgConstant1
); /* divided by 2*/
309 /*FUNCTION**********************************************************************
311 * Function Name : CLOCK_HAL_GetIrclk
312 * Description : Get the current mcg ir clock
313 * This function will return the mcgirclk value in frequency(hz) based
314 * on current mcg configurations and settings. It will not check if the
315 * mcgirclk is enabled or not, just calculate and return the value.
317 *END**************************************************************************/
318 uint32_t CLOCK_HAL_GetInternalRefClk(uint32_t baseAddr
)
321 if (CLOCK_HAL_GetInternalRefClkSelMode(baseAddr
) == kMcgInternalRefClkSelSlow
)
323 /* Slow internal reference clock selected*/
324 mcgirclk
= CPU_INT_SLOW_CLK_HZ
;
328 mcgirclk
= CPU_INT_FAST_CLK_HZ
/ (1 << CLOCK_HAL_GetFastClkInternalRefDivider(baseAddr
));
333 /*FUNCTION**********************************************************************
335 * Function Name : CLOCK_HAL_GetOutclk
336 * Description : Get the current mcg out clock
337 * This function will return the mcgoutclk value in frequency(hz) based on
338 * current mcg configurations and settings. The configuration should be
339 * properly done in order to get the valid value.
341 *END**************************************************************************/
342 uint32_t CLOCK_HAL_GetOutClk(uint32_t baseAddr
)
344 /* Variable to store output clock frequency of the MCG module*/
345 uint32_t mcgoutclk
= 0;
347 if (CLOCK_HAL_GetClkSrcMode(baseAddr
) == kMcgClkSelOut
)
349 #if FSL_FEATURE_MCG_HAS_PLL
350 /* Output of FLL or PLL is selected*/
351 if (CLOCK_HAL_GetPllSelMode(baseAddr
) == kMcgPllSelFll
)
354 mcgoutclk
= CLOCK_HAL_GetFllClk(baseAddr
);
359 #if FSL_FEATURE_MCG_HAS_PLL1
360 if (CLOCK_HAL_GetPllClkSelMode(baseAddr
) != kMcgPllClkSelPll0
)
362 /* PLL1 output is selected*/
363 mcgoutclk
= CLOCK_HAL_GetPll1Clk(baseAddr
);
367 mcgoutclk
= CLOCK_HAL_GetPll0Clk(baseAddr
);
370 mcgoutclk
= CLOCK_HAL_GetPll0Clk(baseAddr
);
371 #endif // FSL_FEATURE_MCG_HAS_PLL1
374 mcgoutclk
= CLOCK_HAL_GetFllClk(baseAddr
);
375 #endif // FSL_FEATURE_MCG_HAS_PLL
377 else if (CLOCK_HAL_GetClkSrcMode(baseAddr
) == kMcgClkSelInternal
)
379 /* Internal reference clock is selected*/
380 mcgoutclk
= CLOCK_HAL_GetInternalRefClk(baseAddr
);
382 else if (CLOCK_HAL_GetClkSrcMode(baseAddr
) == kMcgClkSelExternal
)
384 /* External reference clock is selected*/
386 #if FSL_FEATURE_MCG_USE_OSCSEL /* case 1: use oscsel for outclock */
388 uint32_t oscsel
= CLOCK_HAL_GetOscselMode(baseAddr
);
389 if (oscsel
== kMcgOscselOsc
)
391 #if FSL_FEATURE_MCG_HAS_OSC1
392 /* System oscillator drives MCG clock*/
393 mcgoutclk
= CPU_XTAL0_CLK_HZ
;
395 /* System oscillator drives MCG clock*/
396 mcgoutclk
= CPU_XTAL_CLK_HZ
;
399 else if (oscsel
== kMcgOscselRtc
)
401 /* RTC 32 kHz oscillator drives MCG clock*/
402 mcgoutclk
= CPU_XTAL32k_CLK_HZ
;
404 #if FSL_FEATURE_MCG_HAS_IRC_48M /* case 1.1: IRC 48M exists*/
405 else if (oscsel
== kMcgOscselIrc
)
407 /* IRC 48Mhz oscillator drives MCG clock*/
408 mcgoutclk
= CPU_INT_IRC_CLK_HZ
;
416 #else /* case 2: use default osc0*/
417 /* System oscillator drives MCG clock*/
418 mcgoutclk
= CPU_XTAL_CLK_HZ
;
429 /*******************************************************************************
431 ******************************************************************************/