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