1 /*
2 ** ###################################################################
3 **     Processors:          MIMX8ML6CVNKZ
4 **                          MIMX8ML6DVNLZ
5 **
6 **     Compilers:           GNU C Compiler
7 **                          IAR ANSI C/C++ Compiler for ARM
8 **                          Keil ARM C/C++ Compiler
9 **
10 **     Reference manual:    IMX8MPRM, Rev.D, 12/2020
11 **     Version:             rev. 5.0, 2021-03-01
12 **     Build:               b210301
13 **
14 **     Abstract:
15 **         Provides a system configuration function and a global variable that
16 **         contains the system frequency. It configures the device and initializes
17 **         the oscillator (PLL) that is part of the microcontroller device.
18 **
19 **     Copyright 2016 Freescale Semiconductor, Inc.
20 **     Copyright 2016-2021 NXP
21 **     All rights reserved.
22 **
23 **     SPDX-License-Identifier: BSD-3-Clause
24 **
25 **     http:                 www.nxp.com
26 **     mail:                 support@nxp.com
27 **
28 **     Revisions:
29 **     - rev. 1.0 (2019-10-11)
30 **         Initial version.
31 **     - rev. 2.0 (2020-02-21)
32 **         Rev.B Header.
33 **     - rev. 3.0 (2020-06-22)
34 **         Rev.C Header.
35 **     - rev. 4.0 (2020-11-16)
36 **         Rev.D Header.
37 **     - rev. 5.0 (2021-03-01)
38 **         Rev.D Header Final.
39 **
40 ** ###################################################################
41 */
42 
43 /*!
44  * @file MIMX8ML6_cm7
45  * @version 5.0
46  * @date 2021-03-01
47  * @brief Device specific configuration file for MIMX8ML6_cm7 (implementation
48  *        file)
49  *
50  * Provides a system configuration function and a global variable that contains
51  * the system frequency. It configures the device and initializes the oscillator
52  * (PLL) that is part of the microcontroller device.
53  */
54 
55 #include <stdint.h>
56 #include "fsl_device_registers.h"
57 
58 /*!
59  * @brief CCM reg macros to extract corresponding registers bit field.
60  */
61 #define CCM_BIT_FIELD_VAL(val, mask, shift) (((val)&mask) >> shift)
62 
63 /*!
64  * @brief CCM reg macros to get corresponding registers values.
65  */
66 #define CCM_ANALOG_REG_VAL(base, off) (*((volatile uint32_t *)((uint32_t)(base) + (off))))
67 
68 /*******************************************************************************
69  * Prototypes
70  ******************************************************************************/
71 uint32_t GetFracPllFreq(const volatile uint32_t *base);
72 uint32_t GetIntegerPllFreq(const volatile uint32_t *base);
73 
GetFracPllFreq(const volatile uint32_t * base)74 uint32_t GetFracPllFreq(const volatile uint32_t *base)
75 {
76     uint32_t fracCfg0   = CCM_ANALOG_REG_VAL(base, 0U);
77     uint32_t fracCfg1   = CCM_ANALOG_REG_VAL(base, 4U);
78     uint32_t fracCfg2   = CCM_ANALOG_REG_VAL(base, 8U);
79     uint32_t refClkFreq = 0U;
80     uint64_t fracClk    = 0U;
81 
82     uint8_t refSel   = (uint8_t)CCM_BIT_FIELD_VAL(fracCfg0, CCM_ANALOG_AUDIO_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_MASK,
83                                                 CCM_ANALOG_AUDIO_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_SHIFT);
84     uint32_t mainDiv = CCM_BIT_FIELD_VAL(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_MAIN_DIV_MASK,
85                                          CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_MAIN_DIV_SHIFT);
86     uint8_t preDiv   = (uint8_t)CCM_BIT_FIELD_VAL(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_PRE_DIV_MASK,
87                                                 CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_PRE_DIV_SHIFT);
88     uint8_t postDiv  = (uint8_t)CCM_BIT_FIELD_VAL(fracCfg1, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_POST_DIV_MASK,
89                                                  CCM_ANALOG_AUDIO_PLL1_FDIV_CTL0_PLL_POST_DIV_SHIFT);
90     uint32_t dsm     = CCM_BIT_FIELD_VAL(fracCfg2, CCM_ANALOG_AUDIO_PLL1_FDIV_CTL1_PLL_DSM_MASK,
91                                      CCM_ANALOG_AUDIO_PLL1_FDIV_CTL1_PLL_DSM_SHIFT);
92 
93     if (refSel == 0U) /* OSC 24M Clock */
94     {
95         refClkFreq = CPU_XTAL_SOSC_CLK_24MHZ;
96     }
97     else
98     {
99         refClkFreq = CLK_PAD_CLK; /* CLK_PAD_CLK Clock, please note that the value is 0hz by default, it could be set at
100                                      system_MIMX8MLx_cm7.h :65 */
101     }
102     fracClk = (uint64_t)refClkFreq * ((uint64_t)mainDiv * 65536UL + (uint64_t)dsm) /
103               ((uint64_t)65536UL * preDiv * (1UL << postDiv));
104 
105     return (uint32_t)fracClk;
106 }
107 
GetIntegerPllFreq(const volatile uint32_t * base)108 uint32_t GetIntegerPllFreq(const volatile uint32_t *base)
109 {
110     uint32_t integerCfg0 = CCM_ANALOG_REG_VAL(base, 0U);
111     uint32_t integerCfg1 = CCM_ANALOG_REG_VAL(base, 4U);
112     uint32_t refClkFreq  = 0U;
113     uint64_t pllOutClock = 0U;
114 
115     uint8_t pllBypass = (uint8_t)CCM_BIT_FIELD_VAL(integerCfg0, CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_BYPASS_MASK,
116                                                    CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_BYPASS_SHIFT);
117     uint8_t refSel    = (uint8_t)CCM_BIT_FIELD_VAL(integerCfg0, CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_MASK,
118                                                 CCM_ANALOG_SYS_PLL1_GEN_CTRL_PLL_REF_CLK_SEL_SHIFT);
119     uint32_t mainDiv  = CCM_BIT_FIELD_VAL(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_MAIN_DIV_MASK,
120                                          CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_MAIN_DIV_SHIFT);
121     uint8_t preDiv    = (uint8_t)CCM_BIT_FIELD_VAL(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_PRE_DIV_MASK,
122                                                 CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_PRE_DIV_SHIFT);
123     uint8_t postDiv   = (uint8_t)CCM_BIT_FIELD_VAL(integerCfg1, CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_POST_DIV_MASK,
124                                                  CCM_ANALOG_SYS_PLL1_FDIV_CTL0_PLL_POST_DIV_SHIFT);
125 
126     if (refSel == 0U) /* OSC 24M Clock */
127     {
128         refClkFreq = CPU_XTAL_SOSC_CLK_24MHZ;
129     }
130     else
131     {
132         refClkFreq = CLK_PAD_CLK; /* CLK_PAD_CLK Clock, please note that the value is 0hz by default, it could be set at
133                                      system_MIMX8MLx_cm7.h :65 */
134     }
135 
136     if (pllBypass != 0U)
137     {
138         pllOutClock = refClkFreq;
139     }
140 
141     else
142     {
143         pllOutClock = (uint64_t)refClkFreq * mainDiv / (((uint64_t)(1U) << postDiv) * preDiv);
144     }
145 
146     return (uint32_t)pllOutClock;
147 }
148 
149 /* ----------------------------------------------------------------------------
150    -- Core clock
151    ---------------------------------------------------------------------------- */
152 
153 uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
154 
155 /* ----------------------------------------------------------------------------
156    -- SystemInit()
157    ---------------------------------------------------------------------------- */
158 
SystemInit(void)159 void SystemInit(void)
160 {
161 #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
162     SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access */
163 #endif                                                 /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
164 
165     SystemInitHook();
166 }
167 
168 /* ----------------------------------------------------------------------------
169    -- SystemCoreClockUpdate()
170    ---------------------------------------------------------------------------- */
171 
SystemCoreClockUpdate(void)172 void SystemCoreClockUpdate(void)
173 {
174     volatile uint32_t *M7_ClockRoot = (volatile uint32_t *)(&(CCM)->ROOT[1].TARGET_ROOT);
175     uint32_t pre  = ((*M7_ClockRoot & CCM_TARGET_ROOT_PRE_PODF_MASK) >> CCM_TARGET_ROOT_PRE_PODF_SHIFT) + 1U;
176     uint32_t post = ((*M7_ClockRoot & CCM_TARGET_ROOT_POST_PODF_MASK) >> CCM_TARGET_ROOT_POST_PODF_SHIFT) + 1U;
177 
178     uint32_t freq = 0U;
179 
180     switch ((*M7_ClockRoot & CCM_TARGET_ROOT_MUX_MASK) >> CCM_TARGET_ROOT_MUX_SHIFT)
181     {
182         case 0U: /* OSC 24M Clock */
183             freq = CPU_XTAL_SOSC_CLK_24MHZ;
184             break;
185         case 1U:                                                             /* System PLL2 DIV5 */
186             freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL2_GEN_CTRL)) / 5U; /* Get System PLL2 DIV5 freq */
187             break;
188         case 2U:                                                             /* System PLL2 DIV4 */
189             freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL2_GEN_CTRL)) / 4U; /* Get System PLL2 DIV4 freq */
190             break;
191         case 3U:                                                             /* System PLL1 DIV3 */
192             freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL1_GEN_CTRL)) / 3U; /* Get System PLL1 DIV3 freq */
193             break;
194         case 4U:                                                        /* System PLL1 */
195             freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL1_GEN_CTRL)); /* Get System PLL1 freq */
196             break;
197         case 5U:                                                       /* AUDIO PLL1 */
198             freq = GetFracPllFreq(&(CCM_ANALOG->AUDIO_PLL1_GEN_CTRL)); /* Get AUDIO PLL1 freq */
199             break;
200         case 6U:                                                       /* VIDEO PLL1 */
201             freq = GetFracPllFreq(&(CCM_ANALOG->VIDEO_PLL1_GEN_CTRL)); /* Get VIDEO PLL1 freq */
202             break;
203         case 7U:                                                        /* System PLL3 */
204             freq = GetIntegerPllFreq(&(CCM_ANALOG->SYS_PLL3_GEN_CTRL)); /* Get System PLL3 freq */
205             break;
206         default:
207             freq = CPU_XTAL_SOSC_CLK_24MHZ;
208             break;
209     }
210 
211     SystemCoreClock = freq / pre / post;
212 }
213 
214 /* ----------------------------------------------------------------------------
215    -- SystemInitHook()
216    ---------------------------------------------------------------------------- */
217 
SystemInitHook(void)218 __attribute__((weak)) void SystemInitHook(void)
219 {
220     /* Void implementation of the weak function. */
221 }
222