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 ******************************************************************************/