1 /*
2 ** ###################################################################
3 **     Processors:          MCIMX7U5CVP06
4 **                          MCIMX7U5DVK07
5 **                          MCIMX7U5DVP07
6 **
7 **     Compilers:           GNU C Compiler
8 **                          IAR ANSI C/C++ Compiler for ARM
9 **                          Keil ARM C/C++ Compiler
10 **
11 **     Reference manual:    IMX7ULPRM, Rev. 0, Nov. 2018
12 **     Version:             rev. 7.0, 2018-11-05
13 **     Build:               b200408
14 **
15 **     Abstract:
16 **         Provides a system configuration function and a global variable that
17 **         contains the system frequency. It configures the device and initializes
18 **         the oscillator (PLL) that is part of the microcontroller device.
19 **
20 **     Copyright 2016 Freescale Semiconductor, Inc.
21 **     Copyright 2016-2020 NXP
22 **     All rights reserved.
23 **
24 **     SPDX-License-Identifier: BSD-3-Clause
25 **
26 **     http:                 www.nxp.com
27 **     mail:                 support@nxp.com
28 **
29 **     Revisions:
30 **     - rev. 1.0 (2016-04-13)
31 **         Initial version.
32 **     - rev. 2.0 (2016-07-19)
33 **         RevC Header ER
34 **     - rev. 3.0 (2017-02-28)
35 **         RevD Header ER
36 **     - rev. 4.0 (2017-05-02)
37 **         RevE Header ER
38 **     - rev. 5.0 (2017-12-22)
39 **         RevA(B0) Header GA
40 **     - rev. 6.0 (2018-02-01)
41 **         RevB(B0) Header GA
42 **     - rev. 7.0 (2018-11-05)
43 **         RevA(B1) Header
44 **
45 ** ###################################################################
46 */
47 
48 /*!
49  * @file MCIMX7U5_cm4
50  * @version 7.0
51  * @date 2018-11-05
52  * @brief Device specific configuration file for MCIMX7U5_cm4 (implementation
53  *        file)
54  *
55  * Provides a system configuration function and a global variable that contains
56  * the system frequency. It configures the device and initializes the oscillator
57  * (PLL) that is part of the microcontroller device.
58  */
59 
60 #include <stdint.h>
61 #include "fsl_device_registers.h"
62 
63 
64 
65 typedef void (*WdogFuncPtr)(WDOG_Type *wdog);
66 
67 
68 
69 /* ----------------------------------------------------------------------------
70    -- Core clock
71    ---------------------------------------------------------------------------- */
72 
73 uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
74 
75 /* ----------------------------------------------------------------------------
76    -- SystemInit()
77    ---------------------------------------------------------------------------- */
78 
SystemInit(void)79 void SystemInit (void) {
80 #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
81   SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2));    /* set CP10, CP11 Full Access */
82 #endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
83 
84 
85 /* i.MX7ULP systemInit */
86   WdogFuncPtr WdogDisable;
87   uint16_t WdogDisable32[] = {
88     0xF64D,   /* MOV R1, #0xD928  */
89     0x1128,
90     0xF24C,   /* MOV R2, #0xC520  */
91     0x5220,
92     0xEA4F,   /* LSL R1, R1, #16  */
93     0x4101,
94     0x4411,   /* ADD R1, R1, R2   */
95     0x6041,   /* STR R1, [R0, #4] */
96     0xF64F,   /* MOV R1, #0xFFFF  */
97     0x71FF,
98     0x6081,   /* STR R1, [R0, #8] */
99     0x6801,   /* LDR R1, [R0, #0] */
100     0xF031,   /* BICS R1, R1, #0x80 */
101     0x0180,
102     0xF051,   /* ORRS R1, R1, #0x20 */
103     0x0120,
104     0x6001,   /* STR R1, [R0]     */
105     0x4770    /* BX  LR           */
106   };
107   uint16_t WdogDisable16[] = {
108     0xF24C,   /* MOV R1, #0xC520  */
109     0x5120,
110     0x6041,   /* STR R1, [R0, #4] */
111     0xF64D,   /* MOV R1, #0xD928  */
112     0x1128,
113     0x6041,   /* STR R1, [R0, #4] */
114     0xF64F,   /* MOV R1, #0xFFFF  */
115     0x71FF,
116     0x6081,   /* STR R1, [R0, #8] */
117     0x6801,   /* LDR R1, [R0, #0] */
118     0xF031,   /* BICS R1, R1, #0x80 */
119     0x0180,
120     0xF051,   /* ORRS R1, R1, #0x20 */
121     0x0120,
122     0x6001,   /* STR R1, [R0]     */
123     0x4770    /* BX  LR           */
124   };
125 #if (DISABLE_WDOG)
126   if ((WDOG0->CS & WDOG_CS_EN_MASK) != 0U)
127   {
128     /* WDOG has timing requirement to unlock the operation window.
129        When running in QSPI flash, it's possible to violate that timing
130        requirement. So we put the WDOG operation in RAM */
131     /* Is WDOG 32bit access enabled? */
132     if ((WDOG0->CS & WDOG_CS_CMD32EN_MASK) != 0U)
133     {
134       WdogDisable = (WdogFuncPtr)(((uint32_t)WdogDisable32) | 1U); /* thumb code */
135     }
136     else
137     {
138       WdogDisable = (WdogFuncPtr)(((uint32_t)WdogDisable16) | 1U); /* thumb code */
139     }
140     WdogDisable(WDOG0);
141   }
142 #endif /* (DISABLE_WDOG) */
143   /* set command to invalidate all ways and write GO bit
144      to initiate command */
145   LMEM->PCCCR = LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK;
146   LMEM->PCCCR |= LMEM_PCCCR_GO_MASK;
147   /* Wait until the command completes */
148   while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U)
149   {}
150   /* Enable code bus cache, enable write buffer */
151   LMEM->PCCCR = (LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
152   __ISB();
153   __DSB();
154 
155   SystemInitHook();
156 }
157 
158 /* ----------------------------------------------------------------------------
159    -- SystemCoreClockUpdate()
160    ---------------------------------------------------------------------------- */
161 
SystemCoreClockUpdate(void)162 void SystemCoreClockUpdate (void) {
163 
164 
165   /* i.MX7ULP systemCoreClockUpdate */
166   uint8_t spllMulti[] = {0U, 15U, 16U, 20U, 22U, 25U, 30U, 0U};
167   uint32_t SCGOUTClock, apllNum, apllDenom, apllTmp;
168   /* Identify current system clock source. */
169   switch (SCG0->CSR & SCG_CSR_SCS_MASK)
170   {
171     /* System OSC */
172     case SCG_CSR_SCS(1):
173       SCGOUTClock = CPU_XTAL_SOSC_CLK_HZ;
174       break;
175     /* Slow IRC */
176     case SCG_CSR_SCS(2):
177       SCGOUTClock = ((0u == (SCG0->SIRCCFG & SCG_SIRCCFG_RANGE_MASK)) ? 4000000u : 16000000u);
178       break;
179     /* Fast IRC */
180     case SCG_CSR_SCS(3):
181       SCGOUTClock = 48000000u + ((SCG0->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT) * 4000000u;
182       break;
183     /* RTC OSC */
184     case SCG_CSR_SCS(4):
185       SCGOUTClock = 32768u;
186       break;
187     /* System PLL */
188     case SCG_CSR_SCS(6):
189       /* System clock from SPLL. */
190       SCGOUTClock = (0u == (SCG0->SPLLCFG & SCG_SPLLCFG_SOURCE_MASK)) ? CPU_XTAL_SOSC_CLK_HZ :
191                     (48000000u + ((SCG0->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT) * 4000000u);
192       SCGOUTClock /= ((SCG0->SPLLCFG & SCG_SPLLCFG_PREDIV_MASK) >> SCG_SPLLCFG_PREDIV_SHIFT) + 1u;
193       SCGOUTClock *= spllMulti[((SCG0->SPLLCFG & SCG_SPLLCFG_MULT_MASK) >> SCG_SPLLCFG_MULT_SHIFT)];
194       /* Is Core clock from PLL PFD? */
195       if (0u != (SCG0->SPLLCFG & SCG_SPLLCFG_PLLS_MASK))
196       {
197         /* System clock from SPLL PFD. */
198         switch (SCG0->SPLLCFG & SCG_SPLLCFG_PFDSEL_MASK)
199         {
200           case SCG_SPLLCFG_PFDSEL(0):
201             SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
202                                      ((SCG0->SPLLPFD & SCG_SPLLPFD_PFD0_MASK) >> SCG_SPLLPFD_PFD0_SHIFT));
203             break;
204           case SCG_SPLLCFG_PFDSEL(1):
205             SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
206                                      ((SCG0->SPLLPFD & SCG_SPLLPFD_PFD1_MASK) >> SCG_SPLLPFD_PFD1_SHIFT));
207             break;
208           case SCG_SPLLCFG_PFDSEL(2):
209             SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
210                                      ((SCG0->SPLLPFD & SCG_SPLLPFD_PFD2_MASK) >> SCG_SPLLPFD_PFD2_SHIFT));
211             break;
212           case SCG_SPLLCFG_PFDSEL(3):
213             SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
214                                      ((SCG0->SPLLPFD & SCG_SPLLPFD_PFD3_MASK) >> SCG_SPLLPFD_PFD3_SHIFT));
215             break;
216           default:
217             SCGOUTClock = 0u;
218             break;
219         }
220       }
221       break;
222     /* Auxiliary PLL */
223     case SCG_CSR_SCS(5):
224       /* System clock from APLL. */
225       SCGOUTClock = (0u == (SCG0->APLLCFG & SCG_APLLCFG_SOURCE_MASK)) ? CPU_XTAL_SOSC_CLK_HZ :
226                     (48000000u + ((SCG0->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT) * 4000000u);
227       SCGOUTClock /= ((SCG0->APLLCFG & SCG_APLLCFG_PREDIV_MASK) >> SCG_APLLCFG_PREDIV_SHIFT) + 1u;
228       apllNum = SCG0->APLLNUM;
229       apllDenom = SCG0->APLLDENOM;
230       apllTmp = (uint32_t)((uint64_t)SCGOUTClock * ((uint64_t)apllNum) / ((uint64_t)apllDenom));
231       SCGOUTClock = SCGOUTClock * ((SCG0->APLLCFG & SCG_APLLCFG_MULT_MASK) >> SCG_APLLCFG_MULT_SHIFT) + apllTmp;
232       /* Is Core clock from PLL directly? */
233       if (0u == (SCG0->APLLCFG & SCG_APLLCFG_PLLS_MASK))
234       {
235         /* System clock from APLL directly. */
236         SCGOUTClock /= (((SCG0->APLLCFG & SCG_APLLCFG_PLLPOSTDIV1_MASK) >> SCG_APLLCFG_PLLPOSTDIV1_SHIFT) + 1u);
237         SCGOUTClock /= (((SCG0->APLLCFG & SCG_APLLCFG_PLLPOSTDIV2_MASK) >> SCG_APLLCFG_PLLPOSTDIV2_SHIFT) + 1u);
238       }
239       else
240       {
241         /* System clock from APLL PFD. */
242         switch (SCG0->APLLCFG & SCG_APLLCFG_PFDSEL_MASK)
243         {
244           case SCG_APLLCFG_PFDSEL(0):
245             SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
246                                      ((SCG0->APLLPFD & SCG_APLLPFD_PFD0_MASK) >> SCG_APLLPFD_PFD0_SHIFT));
247             break;
248           case SCG_APLLCFG_PFDSEL(1):
249             SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
250                                      ((SCG0->APLLPFD & SCG_APLLPFD_PFD1_MASK) >> SCG_APLLPFD_PFD1_SHIFT));
251             break;
252           case SCG_APLLCFG_PFDSEL(2):
253             SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
254                                      ((SCG0->APLLPFD & SCG_APLLPFD_PFD2_MASK) >> SCG_APLLPFD_PFD2_SHIFT));
255             break;
256           case SCG_APLLCFG_PFDSEL(3):
257             SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
258                                      ((SCG0->APLLPFD & SCG_APLLPFD_PFD3_MASK) >> SCG_APLLPFD_PFD3_SHIFT));
259             break;
260           default:
261             SCGOUTClock = 0u;
262             break;
263         }
264       }
265       break;
266     /* Can not identify core clock source. */
267     default:
268       SCGOUTClock = 0u;
269       break;
270   }
271   /* Divide the SCG output clock to get the M4 Core clock. */
272   SCGOUTClock /= ((SCG0->CSR & SCG_CSR_DIVCORE_MASK) >> SCG_CSR_DIVCORE_SHIFT) + 1u;
273   /* Update System Core Clock. */
274   SystemCoreClock = SCGOUTClock;
275 
276 }
277 
278 /* ----------------------------------------------------------------------------
279    -- SystemInitHook()
280    ---------------------------------------------------------------------------- */
281 
SystemInitHook(void)282 __attribute__ ((weak)) void SystemInitHook (void) {
283   /* Void implementation of the weak function. */
284 }
285