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