1 /*
2 * Copyright 2024-2025 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/init.h>
10 #include <zephyr/logging/log.h>
11 #include <soc.h>
12 #include <zephyr/linker/sections.h>
13 #include <zephyr/linker/linker-defs.h>
14 #include <zephyr/cache.h>
15 #include <fsl_clock.h>
16 #include <fsl_gpc.h>
17 #include <fsl_pmu.h>
18 #include <fsl_dcdc.h>
19 #include <fsl_ele_base_api.h>
20 #include <fsl_trdc.h>
21 #if defined(CONFIG_WDT_MCUX_RTWDOG)
22 #include <fsl_soc_src.h>
23 #endif
24 #include <zephyr/dt-bindings/clock/imx_ccm_rev2.h>
25 #include <cmsis_core.h>
26
27 LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL);
28
29 #if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)
30 #include <zephyr_image_info.h>
31 /* Memcpy macro to copy segments from secondary core image stored in flash
32 * to RAM section that secondary core boots from.
33 * n is the segment number, as defined in zephyr_image_info.h
34 */
35 #define MEMCPY_SEGMENT(n, _) \
36 memcpy((uint32_t *)(((SEGMENT_LMA_ADDRESS_ ## n) - ADJUSTED_LMA) + 0x303C0000), \
37 (uint32_t *)(SEGMENT_LMA_ADDRESS_ ## n), \
38 (SEGMENT_SIZE_ ## n))
39 #endif
40
41 /*
42 * Set ELE_STICK_FAILED_STS to 0 when ELE status check is not required,
43 * which is useful when debug reset, where the core has already get the
44 * TRDC ownership at first time and ELE is not able to release TRDC
45 * ownership again for the following TRDC ownership request.
46 */
47 #define ELE_STICK_FAILED_STS 1
48
49 #if ELE_STICK_FAILED_STS
50 #define ELE_IS_FAILED(x) (x != kStatus_Success)
51 #else
52 #define ELE_IS_FAILED(x) false
53 #endif
54
55 #define ELE_TRDC_AON_ID 0x74
56 #define ELE_TRDC_WAKEUP_ID 0x78
57 #define ELE_CORE_CM33_ID 0x1
58 #define ELE_CORE_CM7_ID 0x2
59 #define EDMA_DID 0x7U
60
61 /* When CM33 sets TRDC, CM7 must NOT require TRDC ownership from ELE */
62 #if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_SOC_MIMXRT1189_CM7)
63 /* When CONFIG_SECOND_CORE_MCUX then TRDC(AON/WAKEUP) ownership cannot be released
64 * to CM33 and CM7 both in one ELE reset cycle.
65 * Only CM33 will set TRDC.
66 */
67 #define CM33_SET_TRDC 0U
68 #else
69 #define CM33_SET_TRDC 1U
70 #endif
71
72 #ifdef CONFIG_INIT_ARM_PLL
73 static const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = {
74 #if defined(CONFIG_SOC_MIMXRT1189_CM33) || defined(CONFIG_SOC_MIMXRT1189_CM7)
75 /* Post divider, 0 - DIV by 2, 1 - DIV by 4, 2 - DIV by 8, 3 - DIV by 1 */
76 .postDivider = kCLOCK_PllPostDiv2,
77 /* PLL Loop divider, Fout = Fin * ( loopDivider / ( 2 * postDivider ) ) */
78 .loopDivider = 132,
79 #else
80 #error "Unknown SOC, no pll configuration defined"
81 #endif
82 };
83 #endif
84
85 #if defined(CONFIG_WDT_MCUX_RTWDOG)
86 #define RTWDOG_IF_SET_SRC(n, i) \
87 if (IS_ENABLED(DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(rtwdog##n), nxp_rtwdog, okay))) { \
88 SRC_SetGlobalSystemResetMode(SRC_GENERAL_REG, kSRC_Wdog##i##Reset, \
89 kSRC_ResetSystem); \
90 }
91 #endif
92
93 const clock_sys_pll1_config_t sysPll1Config_BOARD_BootClockRUN = {
94 /* Enable Sys Pll1 divide-by-2 clock or not */
95 .pllDiv2En = 1,
96 /* Enable Sys Pll1 divide-by-5 clock or not */
97 .pllDiv5En = 1,
98 /* Spread spectrum parameter */
99 .ss = NULL,
100 /* Enable spread spectrum or not */
101 .ssEnable = false,
102 };
103
104 const clock_sys_pll2_config_t sysPll2Config_BOARD_BootClockRUN = {
105 /* Denominator of spread spectrum */
106 .mfd = 268435455,
107 /* Spread spectrum parameter */
108 .ss = NULL,
109 /* Enable spread spectrum or not */
110 .ssEnable = false,
111 };
112
113 /* Function Name : board_flexspi_clock_safe_config
114 * Description : FLEXSPI clock source safe configuration weak function.
115 * Called before clock source configuration.
116 * Note : Users need override this function to change FLEXSPI clock source to stable
117 * source when executing code on FLEXSPI memory(XIP). If XIP, the function
118 * should runs in RAM and move the FLEXSPI clock source to a stable clock
119 * to avoid instruction/data fetch issue during clock updating.
120 */
board_flexspi_clock_safe_config(void)121 __attribute__((weak)) void board_flexspi_clock_safe_config(void)
122 {
123 }
124
125 /**
126 * @brief Initialize the system clock
127 */
clock_init(void)128 __weak void clock_init(void)
129 {
130 clock_root_config_t rootCfg = {0};
131
132 /* Init OSC RC 400M */
133 CLOCK_OSC_EnableOscRc400M();
134 CLOCK_OSC_GateOscRc400M(false);
135
136 #if CONFIG_CPU_CORTEX_M7
137 /* Switch both core to OscRC400M first */
138 rootCfg.mux = kCLOCK_M7_ClockRoot_MuxOscRc400M;
139 rootCfg.div = 1;
140 CLOCK_SetRootClock(kCLOCK_Root_M7, &rootCfg);
141 #endif
142
143 #if CONFIG_CPU_CORTEX_M33
144 rootCfg.mux = kCLOCK_M33_ClockRoot_MuxOscRc400M;
145 rootCfg.div = 2;
146 CLOCK_SetRootClock(kCLOCK_Root_M33, &rootCfg);
147 #endif
148
149 #if CONFIG_CPU_CORTEX_M7
150 DCDC_SetVDD1P0BuckModeTargetVoltage(DCDC, kDCDC_CORE0, kDCDC_1P0Target1P1V);
151 DCDC_SetVDD1P0BuckModeTargetVoltage(DCDC, kDCDC_CORE1, kDCDC_1P0Target1P1V);
152 /* FBB need to be enabled in OverDrive(OD) mode */
153 PMU_EnableFBB(ANADIG_PMU, true);
154 #endif
155
156 /* Config CLK_1M */
157 CLOCK_OSC_Set1MHzOutputBehavior(kCLOCK_1MHzOutEnableFreeRunning1Mhz);
158
159 /* Init OSC RC 24M */
160 CLOCK_OSC_EnableOscRc24M(true);
161
162 /* Config OSC 24M */
163 ANADIG_OSC->OSC_24M_CTRL |= ANADIG_OSC_OSC_24M_CTRL_OSC_EN(1) |
164 ANADIG_OSC_OSC_24M_CTRL_BYPASS_EN(0) | ANADIG_OSC_OSC_24M_CTRL_LP_EN(1) |
165 ANADIG_OSC_OSC_24M_CTRL_OSC_24M_GATE(0);
166
167 /* Wait for 24M OSC to be stable. */
168 while (ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK !=
169 (ANADIG_OSC->OSC_24M_CTRL & ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK)) {
170 }
171
172 /* Call function board_flexspi_clock_safe_config() to move FlexSPI clock to a stable
173 * clock source to avoid instruction/data fetch issue when updating PLL if XIP
174 * (execute code on FLEXSPI memory).
175 */
176 board_flexspi_clock_safe_config();
177
178 #ifdef CONFIG_INIT_ARM_PLL
179 /* Init Arm Pll. */
180 CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN);
181 #endif
182
183 /* Init Sys Pll1. */
184 CLOCK_InitSysPll1(&sysPll1Config_BOARD_BootClockRUN);
185
186 /* Init Sys Pll2. */
187 CLOCK_InitSysPll2(&sysPll2Config_BOARD_BootClockRUN);
188 /* Init System Pll2 pfd0. */
189 CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd0, 27);
190 /* Init System Pll2 pfd1. */
191 CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd1, 16);
192 /* Init System Pll2 pfd2. */
193 CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd2, 24);
194 /* Init System Pll2 pfd3. */
195 CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd3, 32);
196
197 /* Init Sys Pll3. */
198 CLOCK_InitSysPll3();
199 /* Init System Pll3 pfd0. */
200 CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd0, 22);
201 /* Init System Pll3 pfd1. */
202 CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd1, 33);
203 /* Init System Pll3 pfd2. */
204 CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd2, 22);
205 /* Init System Pll3 pfd3. */
206 CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd3, 18);
207
208 /* Bypass Audio Pll. */
209 CLOCK_SetPllBypass(kCLOCK_PllAudio, true);
210 /* DeInit Audio Pll. */
211 CLOCK_DeinitAudioPll();
212
213 #if defined(CONFIG_SOC_MIMXRT1189_CM7)
214 /* Module clock root configurations. */
215 /* Configure M7 using ARM_PLL_CLK */
216 rootCfg.mux = kCLOCK_M7_ClockRoot_MuxArmPllOut;
217 rootCfg.div = 1;
218 CLOCK_SetRootClock(kCLOCK_Root_M7, &rootCfg);
219 #endif
220
221 #if defined(CONFIG_SOC_MIMXRT1189_CM33)
222 /* Configure M33 using SYS_PLL3_CLK */
223 rootCfg.mux = kCLOCK_M33_ClockRoot_MuxSysPll3Out;
224 rootCfg.div = 2;
225 CLOCK_SetRootClock(kCLOCK_Root_M33, &rootCfg);
226 #endif
227
228 /* Configure BUS_AON using SYS_PLL2_CLK */
229 rootCfg.mux = kCLOCK_BUS_AON_ClockRoot_MuxSysPll2Out;
230 rootCfg.div = 4;
231 CLOCK_SetRootClock(kCLOCK_Root_Bus_Aon, &rootCfg);
232
233 /* Configure BUS_WAKEUP using SYS_PLL2_CLK */
234 rootCfg.mux = kCLOCK_BUS_WAKEUP_ClockRoot_MuxSysPll2Out;
235 rootCfg.div = 4;
236 CLOCK_SetRootClock(kCLOCK_Root_Bus_Wakeup, &rootCfg);
237
238 /* Configure WAKEUP_AXI using SYS_PLL3_CLK */
239 rootCfg.mux = kCLOCK_WAKEUP_AXI_ClockRoot_MuxSysPll3Out;
240 rootCfg.div = 2;
241 CLOCK_SetRootClock(kCLOCK_Root_Wakeup_Axi, &rootCfg);
242
243 /* Configure SWO_TRACE using SYS_PLL3_DIV2_CLK */
244 rootCfg.mux = kCLOCK_SWO_TRACE_ClockRoot_MuxSysPll3Div2;
245 rootCfg.div = 3;
246 CLOCK_SetRootClock(kCLOCK_Root_Swo_Trace, &rootCfg);
247
248 #if CONFIG_CPU_CORTEX_M33
249 /* Configure M33_SYSTICK using OSC_24M */
250 rootCfg.mux = kCLOCK_M33_SYSTICK_ClockRoot_MuxOsc24MOut;
251 rootCfg.div = 240;
252 CLOCK_SetRootClock(kCLOCK_Root_M33_Systick, &rootCfg);
253 #endif
254
255 #if CONFIG_CPU_CORTEX_M7
256 /* Configure M7_SYSTICK using OSC_24M */
257 rootCfg.mux = kCLOCK_M7_SYSTICK_ClockRoot_MuxOsc24MOut;
258 rootCfg.div = 240;
259 CLOCK_SetRootClock(kCLOCK_Root_M7_Systick, &rootCfg);
260 #endif
261
262 #if defined(CONFIG_UART_MCUX_LPUART) && \
263 (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart1)) \
264 || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart2)))
265 /* Configure LPUART0102 using SYS_PLL3_DIV2_CLK */
266 rootCfg.mux = kCLOCK_LPUART0102_ClockRoot_MuxSysPll3Div2;
267 rootCfg.div = 10;
268 #endif
269
270 #if defined(CONFIG_I2C_MCUX_LPI2C) && \
271 (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c1)) \
272 || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c2)))
273 /* Configure LPI2C0102 using SYS_PLL3_DIV2_CLK */
274 rootCfg.mux = kCLOCK_LPI2C0102_ClockRoot_MuxSysPll3Div2;
275 rootCfg.div = 4;
276 CLOCK_SetRootClock(kCLOCK_Root_Lpi2c0102, &rootCfg);
277 #endif
278
279 #if defined(CONFIG_I2C_MCUX_LPI2C) && \
280 (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c3)) \
281 || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c4)))
282 /* Configure LPI2C0304 using SYS_PLL3_DIV2_CLK */
283 rootCfg.mux = kCLOCK_LPI2C0304_ClockRoot_MuxSysPll3Div2;
284 rootCfg.div = 4;
285 CLOCK_SetRootClock(kCLOCK_Root_Lpi2c0304, &rootCfg);
286 #endif
287
288 #if defined(CONFIG_I2C_MCUX_LPI2C) && \
289 (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c5)) \
290 || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c6)))
291 /* Configure LPI2C0506 using SYS_PLL3_DIV2_CLK */
292 rootCfg.mux = kCLOCK_LPI2C0506_ClockRoot_MuxSysPll3Div2;
293 rootCfg.div = 4;
294 CLOCK_SetRootClock(kCLOCK_Root_Lpi2c0506, &rootCfg);
295 #endif
296
297 #if defined(CONFIG_SPI_MCUX_LPSPI)
298
299 #if (DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi1), okay) \
300 || DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi2), okay))
301 /* Configure LPSPI0102 using SYS_PLL3_PFD1_CLK */
302 rootCfg.mux = kCLOCK_LPSPI0102_ClockRoot_MuxSysPll3Pfd1;
303 rootCfg.div = 2;
304 CLOCK_SetRootClock(kCLOCK_Root_Lpspi0102, &rootCfg);
305 #endif
306
307 #if (DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi3), okay) \
308 || DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi4), okay))
309 /* Configure LPSPI0304 using SYS_PLL3_PFD1_CLK */
310 rootCfg.mux = kCLOCK_LPSPI0304_ClockRoot_MuxSysPll3Pfd1;
311 rootCfg.div = 2;
312 CLOCK_SetRootClock(kCLOCK_Root_Lpspi0304, &rootCfg);
313 #endif
314
315 #if (DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi5), okay) \
316 || DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi6), okay))
317 /* Configure LPSPI0506 using SYS_PLL3_PFD1_CLK */
318 rootCfg.mux = kCLOCK_LPSPI0506_ClockRoot_MuxSysPll3Pfd1;
319 rootCfg.div = 2;
320 CLOCK_SetRootClock(kCLOCK_Root_Lpspi0506, &rootCfg);
321 #endif
322
323 #endif /* CONFIG_SPI_MCUX_LPSPI */
324
325 #if defined(CONFIG_COUNTER_MCUX_GPT)
326
327 #if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpt1)))
328 /* Configure GPT1 using SYS_PLL3_DIV2_CLK */
329 rootCfg.mux = kCLOCK_GPT1_ClockRoot_MuxSysPll3Div2;
330 rootCfg.div = 1;
331 CLOCK_SetRootClock(kCLOCK_Root_Gpt1, &rootCfg);
332 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpt1)) */
333
334 #if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpt2)))
335 /* Configure GPT2 using SYS_PLL3_DIV2_CLK */
336 rootCfg.mux = kCLOCK_GPT2_ClockRoot_MuxSysPll3Div2;
337 rootCfg.div = 1;
338 CLOCK_SetRootClock(kCLOCK_Root_Gpt2, &rootCfg);
339 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpt2)) */
340
341 #endif /* CONFIG_COUNTER_MCUX_GPT */
342
343 #ifdef CONFIG_MCUX_ACMP
344
345 #if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(acmp1)) \
346 || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(acmp2)) \
347 || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(acmp3)) \
348 || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(acmp4)))
349 /* Configure ACMP using MuxSysPll3Out */
350 rootCfg.mux = kCLOCK_ACMP_ClockRoot_MuxSysPll3Out;
351 rootCfg.div = 2;
352 CLOCK_SetRootClock(kCLOCK_Root_Acmp, &rootCfg);
353 #endif
354
355 #endif /* CONFIG_MCUX_ACMP */
356
357 #if defined(CONFIG_ETH_NXP_IMX_NETC) && (DT_CHILD_NUM_STATUS_OKAY(DT_NODELABEL(netc)) != 0)
358 /* Configure ENET using SYS_PLL1_DIV2_CLK */
359 rootCfg.mux = kCLOCK_ENET_ClockRoot_MuxSysPll1Div2;
360 rootCfg.div = 4;
361 CLOCK_SetRootClock(kCLOCK_Root_Enet, &rootCfg);
362
363 /* Configure TMR_1588 using SYS_PLL3_CLK */
364 rootCfg.mux = kCLOCK_TMR_1588_ClockRoot_MuxSysPll3Out;
365 rootCfg.div = 2;
366 CLOCK_SetRootClock(kCLOCK_Root_Tmr_1588, &rootCfg);
367
368 /* Configure NETC using SYS_PLL3_PFD3_CLK */
369 rootCfg.mux = kCLOCK_NETC_ClockRoot_MuxSysPll3Pfd3;
370 rootCfg.div = 2;
371 CLOCK_SetRootClock(kCLOCK_Root_Netc, &rootCfg);
372
373 /* Configure MAC0 using SYS_PLL1_DIV2_CLK */
374 rootCfg.mux = kCLOCK_MAC0_ClockRoot_MuxSysPll1Div2;
375 rootCfg.div = 10;
376 CLOCK_SetRootClock(kCLOCK_Root_Mac0, &rootCfg);
377
378 /* Configure MAC1 using SYS_PLL1_DIV2_CLK */
379 rootCfg.mux = kCLOCK_MAC1_ClockRoot_MuxSysPll1Div2;
380 rootCfg.div = 4;
381 CLOCK_SetRootClock(kCLOCK_Root_Mac1, &rootCfg);
382
383 /* Configure MAC2 using SYS_PLL1_DIV2_CLK */
384 rootCfg.mux = kCLOCK_MAC2_ClockRoot_MuxSysPll1Div2;
385 rootCfg.div = 4;
386 CLOCK_SetRootClock(kCLOCK_Root_Mac2, &rootCfg);
387
388 /* Configure MAC3 using SYS_PLL1_DIV2_CLK */
389 rootCfg.mux = kCLOCK_MAC3_ClockRoot_MuxSysPll1Div2;
390 rootCfg.div = 4;
391 CLOCK_SetRootClock(kCLOCK_Root_Mac3, &rootCfg);
392
393 /* Configure MAC4 using SYS_PLL1_DIV2_CLK */
394 rootCfg.mux = kCLOCK_MAC4_ClockRoot_MuxSysPll1Div2;
395 rootCfg.div = 10;
396 CLOCK_SetRootClock(kCLOCK_Root_Mac4, &rootCfg);
397
398 /* Set NETC PORT Ref clock source. */
399 BLK_CTRL_WAKEUPMIX->NETC_PORT_MISC_CFG &=
400 ~BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_PORT0_RMII_REF_CLK_DIR_MASK;
401 BLK_CTRL_WAKEUPMIX->NETC_PORT_MISC_CFG &=
402 ~BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_PORT1_RMII_REF_CLK_DIR_MASK;
403 BLK_CTRL_WAKEUPMIX->NETC_PORT_MISC_CFG &=
404 ~BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_PORT2_RMII_REF_CLK_DIR_MASK;
405 BLK_CTRL_WAKEUPMIX->NETC_PORT_MISC_CFG &=
406 ~BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_PORT3_RMII_REF_CLK_DIR_MASK;
407 BLK_CTRL_WAKEUPMIX->NETC_PORT_MISC_CFG &=
408 ~BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_PORT4_RMII_REF_CLK_DIR_MASK;
409
410 /* Set TMR 1588 Ref clock source. */
411 BLK_CTRL_WAKEUPMIX->NETC_PORT_MISC_CFG |=
412 BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_TMR_EXT_CLK_SEL_MASK;
413 #endif
414
415 #ifdef CONFIG_CAN_MCUX_FLEXCAN
416
417 #if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan1), okay)
418 /* Configure CAN1 using MuxSysPll3Out */
419 rootCfg.mux = kCLOCK_CAN1_ClockRoot_MuxSysPll3Out;
420 rootCfg.div = 6;
421 CLOCK_SetRootClock(kCLOCK_Root_Can1, &rootCfg);
422 #endif
423
424 #if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan2), okay)
425 /* Configure CAN2 using MuxSysPll3Out */
426 rootCfg.mux = kCLOCK_CAN2_ClockRoot_MuxSysPll3Out;
427 rootCfg.div = 6;
428 CLOCK_SetRootClock(kCLOCK_Root_Can2, &rootCfg);
429 #endif
430
431 #if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcan3), okay)
432 /* Configure CAN3 using MuxSysPll3Out */
433 rootCfg.mux = kCLOCK_CAN3_ClockRoot_MuxSysPll3Out;
434 rootCfg.div = 6;
435 CLOCK_SetRootClock(kCLOCK_Root_Can3, &rootCfg);
436 #endif
437
438 #endif /* CONFIG_CAN_MCUX_FLEXCAN */
439
440 #if defined(CONFIG_MCUX_LPTMR_TIMER) || defined(CONFIG_COUNTER_MCUX_LPTMR)
441
442 #if DT_NODE_HAS_STATUS(DT_NODELABEL(lptmr1), okay)
443 /* Configure LPTIMER1 using SYS_PLL3_DIV2_CLK */
444 rootCfg.mux = kCLOCK_LPTIMER1_ClockRoot_MuxSysPll3Div2;
445 rootCfg.div = 3;
446 CLOCK_SetRootClock(kCLOCK_Root_Lptimer1, &rootCfg);
447 #endif
448
449 #if DT_NODE_HAS_STATUS(DT_NODELABEL(lptmr2), okay)
450 /* Configure LPTIMER2 using SYS_PLL3_DIV2_CLK */
451 rootCfg.mux = kCLOCK_LPTIMER2_ClockRoot_MuxSysPll3Div2;
452 rootCfg.div = 3;
453 CLOCK_SetRootClock(kCLOCK_Root_Lptimer2, &rootCfg);
454 #endif
455
456 #if DT_NODE_HAS_STATUS(DT_NODELABEL(lptmr3), okay)
457 /* Configure LPTIMER3 using SYS_PLL3_DIV2_CLK */
458 rootCfg.mux = kCLOCK_LPTIMER3_ClockRoot_MuxSysPll3Div2;
459 rootCfg.div = 3;
460 CLOCK_SetRootClock(kCLOCK_Root_Lptimer3, &rootCfg);
461 #endif
462
463 #endif /* CONFIG_MCUX_LPTMR_TIMER || CONFIG_COUNTER_MCUX_LPTMR */
464
465 #if !(DT_NODE_HAS_COMPAT(DT_PARENT(DT_CHOSEN(zephyr_flash)), nxp_imx_flexspi_nor)) && \
466 defined(CONFIG_MEMC_MCUX_FLEXSPI) && DT_NODE_HAS_STATUS(DT_NODELABEL(flexspi), okay)
467 /* Configure FLEXSPI1 using SYS_PLL3_PFD0_CLK */
468 rootCfg.mux = kCLOCK_FLEXSPI1_ClockRoot_MuxSysPll3Pfd0;
469 rootCfg.div = 3;
470 CLOCK_SetRootClock(kCLOCK_Root_Flexspi1, &rootCfg);
471 #endif
472
473 #ifdef CONFIG_HAS_MCUX_TPM
474
475 #if DT_NODE_HAS_STATUS(DT_NODELABEL(tpm2), okay)
476 /* Configure TPM2 using SYS_PLL3_DIV2_CLK */
477 rootCfg.mux = kCLOCK_TPM2_ClockRoot_MuxSysPll3Div2;
478 rootCfg.div = 3;
479 CLOCK_SetRootClock(kCLOCK_Root_Tpm2, &rootCfg);
480 #endif
481
482 #if DT_NODE_HAS_STATUS(DT_NODELABEL(tpm4), okay)
483 /* Configure TPM4 using SYS_PLL3_DIV2_CLK */
484 rootCfg.mux = kCLOCK_TPM4_ClockRoot_MuxSysPll3Div2;
485 rootCfg.div = 3;
486 CLOCK_SetRootClock(kCLOCK_Root_Tpm4, &rootCfg);
487 #endif
488
489 #if DT_NODE_HAS_STATUS(DT_NODELABEL(tpm5), okay)
490 /* Configure TPM5 using SYS_PLL3_DIV2_CLK */
491 rootCfg.mux = kCLOCK_TPM5_ClockRoot_MuxSysPll3Div2;
492 rootCfg.div = 3;
493 CLOCK_SetRootClock(kCLOCK_Root_Tpm5, &rootCfg);
494 #endif
495
496 #if DT_NODE_HAS_STATUS(DT_NODELABEL(tpm6), okay)
497 /* Configure TPM6 using SYS_PLL3_DIV2_CLK */
498 rootCfg.mux = kCLOCK_TPM6_ClockRoot_MuxSysPll3Div2;
499 rootCfg.div = 3;
500 CLOCK_SetRootClock(kCLOCK_Root_Tpm6, &rootCfg);
501 #endif
502
503 #endif /* CONFIG_HAS_MCUX_TPM */
504
505 #ifdef CONFIG_DT_HAS_NXP_MCUX_I3C_ENABLED
506
507 #if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c1), okay)
508 /* Configure I3C1 using SYS_PLL3_DIV2_CLK */
509 rootCfg.mux = kCLOCK_I3C1_ClockRoot_MuxSysPll3Div2;
510 rootCfg.div = 10;
511 CLOCK_SetRootClock(kCLOCK_Root_I3c1, &rootCfg);
512 #endif
513
514 #if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c2), okay)
515 /* Configure I3C2 using SYS_PLL3_DIV2_CLK */
516 rootCfg.mux = kCLOCK_I3C2_ClockRoot_MuxSysPll3Div2;
517 rootCfg.div = 10;
518 CLOCK_SetRootClock(kCLOCK_Root_I3c2, &rootCfg);
519 #endif
520
521 #endif /* CONFIG_DT_HAS_NXP_MCUX_I3C_ENABLED */
522
523 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb1)) && CONFIG_UDC_NXP_EHCI
524 CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usb480M,
525 DT_PROP_BY_PHANDLE(DT_NODELABEL(usb1), clocks, clock_frequency));
526 CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M,
527 DT_PROP_BY_PHANDLE(DT_NODELABEL(usb1), clocks, clock_frequency));
528 #endif
529
530 #ifdef CONFIG_IMX_USDHC
531
532 #if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc1), okay)
533 /* Configure USDHC1 using SysPll2Pfd2 */
534 rootCfg.mux = kCLOCK_USDHC1_ClockRoot_MuxSysPll2Pfd2;
535 rootCfg.div = 2;
536 CLOCK_SetRootClock(kCLOCK_Root_Usdhc1, &rootCfg);
537 #endif
538
539 #if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc2), okay)
540 /* Configure USDHC2 using SysPll2Pfd2 */
541 rootCfg.mux = kCLOCK_USDHC2_ClockRoot_MuxSysPll2Pfd2;
542 rootCfg.div = 2;
543 CLOCK_SetRootClock(kCLOCK_Root_Usdhc2, &rootCfg);
544 #endif
545
546 #endif /* CONFIG_IMX_USDHC */
547
548 /* Keep core clock ungated during WFI */
549 CCM->LPCG[1].LPM0 = 0x33333333;
550 CCM->LPCG[1].LPM1 = 0x33333333;
551
552 /* Let the core clock still running in WAIT mode */
553 BLK_CTRL_S_AONMIX->M7_CFG |= BLK_CTRL_S_AONMIX_M7_CFG_CORECLK_FORCE_ON_MASK;
554
555 /* Keep the system clock running so SYSTICK can wake up
556 * the system from wfi.
557 */
558 GPC_CM_SetNextCpuMode(0, kGPC_RunMode);
559 GPC_CM_SetNextCpuMode(1, kGPC_RunMode);
560 GPC_CM_EnableCpuSleepHold(0, false);
561 GPC_CM_EnableCpuSleepHold(1, false);
562 }
563
564 /**
565 * @brief Initialize the system clock
566 */
trdc_enable_all_access(void)567 static ALWAYS_INLINE void trdc_enable_all_access(void)
568 {
569 status_t sts;
570 uint8_t i, j;
571
572 /* Get ELE FW status */
573 do {
574 uint32_t ele_fw_sts;
575
576 sts = ELE_BaseAPI_GetFwStatus(MU_RT_S3MUA, &ele_fw_sts);
577 } while (sts != kStatus_Success);
578
579 #if defined(CONFIG_SOC_MIMXRT1189_CM33)
580 /* Release TRDC AON to CM33 core */
581 sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_AON_ID, ELE_CORE_CM33_ID);
582 #elif defined(CONFIG_SOC_MIMXRT1189_CM7)
583 /* Release TRDC AON to CM7 core */
584 sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_AON_ID, ELE_CORE_CM7_ID);
585 #endif
586 if (sts != kStatus_Success) {
587 LOG_WRN("warning: TRDC AON permission get failed. If core don't get TRDC "
588 "AON permission, AON domain permission can't be configured.");
589 }
590
591 #if defined(CONFIG_SOC_MIMXRT1189_CM33)
592 /* Release TRDC Wakeup to CM33 core */
593 sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_WAKEUP_ID, ELE_CORE_CM33_ID);
594 #elif defined(CONFIG_SOC_MIMXRT1189_CM7)
595 /* Release TRDC Wakeup to CM7 core */
596 sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_WAKEUP_ID, ELE_CORE_CM7_ID);
597 #endif
598 if (sts != kStatus_Success) {
599 LOG_WRN("warning: TRDC Wakeup permission get failed. If core don't get TRDC "
600 "Wakeup permission, Wakeup domain permission can't be configured.");
601 }
602
603 /* Set the master domain access configuration for eDMA3/eDMA4 */
604 trdc_non_processor_domain_assignment_t edmaAssignment;
605
606 /* By default, EDMA access is done in privilege and security mode,
607 * However, the NSE bit reset value in TRDC is 0, so that TRDC does
608 * not allow nonsecurity access to other memory by default.
609 * So by DAC module, EDMA access mode is changed to security/privilege
610 * mode by the DAC module
611 */
612 (void)memset(&edmaAssignment, 0, sizeof(edmaAssignment));
613 edmaAssignment.domainId = EDMA_DID;
614 edmaAssignment.privilegeAttr = kTRDC_MasterPrivilege;
615 edmaAssignment.secureAttr = kTRDC_ForceSecure;
616 edmaAssignment.bypassDomainId = true;
617 edmaAssignment.lock = false;
618
619 TRDC_SetNonProcessorDomainAssignment(TRDC1, kTRDC1_MasterDMA3, &edmaAssignment);
620 TRDC_SetNonProcessorDomainAssignment(TRDC2, kTRDC2_MasterDMA4, &edmaAssignment);
621
622 /* Enable all access modes for MBC and MRC of TRDCA and TRDCW */
623 trdc_hardware_config_t hwConfig;
624 trdc_memory_access_control_config_t memAccessConfig;
625
626 (void)memset(&memAccessConfig, 0, sizeof(memAccessConfig));
627 memAccessConfig.nonsecureUsrX = 1U;
628 memAccessConfig.nonsecureUsrW = 1U;
629 memAccessConfig.nonsecureUsrR = 1U;
630 memAccessConfig.nonsecurePrivX = 1U;
631 memAccessConfig.nonsecurePrivW = 1U;
632 memAccessConfig.nonsecurePrivR = 1U;
633 memAccessConfig.secureUsrX = 1U;
634 memAccessConfig.secureUsrW = 1U;
635 memAccessConfig.secureUsrR = 1U;
636 memAccessConfig.securePrivX = 1U;
637 memAccessConfig.securePrivW = 1U;
638 memAccessConfig.securePrivR = 1U;
639
640 TRDC_GetHardwareConfig(TRDC1, &hwConfig);
641 for (i = 0U; i < hwConfig.mrcNumber; i++) {
642 /* Set TRDC1(A) secure access for eDMA domain, MRC i, all region for i memory */
643 TRDC_MrcDomainNseClear(TRDC1, i, 1UL << EDMA_DID);
644
645 for (j = 0U; j < 8; j++) {
646 TRDC_MrcSetMemoryAccessConfig(TRDC1, &memAccessConfig, i, j);
647 }
648 }
649
650 for (i = 0U; i < hwConfig.mbcNumber; i++) {
651 /* Set TRDC1(A) secure access for eDMA domain, MBC i, all memory blocks */
652 TRDC_MbcNseClearAll(TRDC1, i, 1UL << EDMA_DID, 0xF);
653
654 for (j = 0U; j < 8; j++) {
655 TRDC_MbcSetMemoryAccessConfig(TRDC1, &memAccessConfig, i, j);
656 }
657 }
658
659 TRDC_GetHardwareConfig(TRDC2, &hwConfig);
660 for (i = 0U; i < hwConfig.mrcNumber; i++) {
661 /* Set TRDC2(W) secure access for eDMA domain, MRC i, all region for i memory */
662 TRDC_MrcDomainNseClear(TRDC2, i, 1UL << EDMA_DID);
663
664 for (j = 0U; j < 8; j++) {
665 TRDC_MrcSetMemoryAccessConfig(TRDC2, &memAccessConfig, i, j);
666 }
667 }
668
669 for (i = 0U; i < hwConfig.mbcNumber; i++) {
670 /* Set TRDC2(W) secure access for eDMA domain, MBC i, all memory blocks */
671 TRDC_MbcNseClearAll(TRDC2, i, 1UL << EDMA_DID, 0xF);
672
673 for (j = 0U; j < 8; j++) {
674 TRDC_MbcSetMemoryAccessConfig(TRDC2, &memAccessConfig, i, j);
675 }
676 }
677 }
678
679 /**
680 *
681 * @brief Perform basic hardware initialization
682 *
683 * Initialize the interrupt controller device drivers.
684 * Also initialize the timer device driver, if required.
685 * If dual core operation is enabled, the second core image will be loaded to RAM
686 *
687 * @return 0
688 */
689
soc_early_init_hook(void)690 void soc_early_init_hook(void)
691 {
692 /* Initialize system clock */
693 clock_init();
694
695 #if (defined(CM33_SET_TRDC) && (CM33_SET_TRDC > 0U))
696 /* Get trdc and enable all access modes for MBC and MRC of TRDCA and TRDCW */
697 trdc_enable_all_access();
698 #endif /* (defined(CM33_SET_TRDC) && (CM33_SET_TRDC > 0U) */
699
700 #if defined(CONFIG_WDT_MCUX_RTWDOG)
701 /* Unmask the watchdog reset channel */
702 RTWDOG_IF_SET_SRC(0, 1)
703 RTWDOG_IF_SET_SRC(1, 2)
704 RTWDOG_IF_SET_SRC(2, 3)
705 RTWDOG_IF_SET_SRC(3, 4)
706 RTWDOG_IF_SET_SRC(4, 5)
707
708 /* Clear the reset status otherwise TCM memory will reload in next reset */
709 uint32_t mask = SRC_GetResetStatusFlags(SRC_GENERAL_REG);
710
711 SRC_ClearGlobalSystemResetStatus(SRC_GENERAL_REG, mask);
712 #endif /* defined(CONFIG_WDT_MCUX_RTWDOG) */
713
714 #if (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33))
715 /**
716 * Copy CM7 core from flash to memory. Note that depending on where the
717 * user decided to store CM7 code, this is likely going to read from the
718 * flexspi while using XIP. Provided we DO NOT WRITE TO THE FLEXSPI,
719 * this operation is safe.
720 *
721 * Note that this copy MUST occur before enabling the M33 caching to
722 * ensure the data is written directly to RAM (since the M4 core will use it)
723 */
724 LISTIFY(SEGMENT_NUM, MEMCPY_SEGMENT, (;));
725 #endif /* (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) */
726
727 /* Enable data cache */
728 sys_cache_data_enable();
729
730 __ISB();
731 __DSB();
732 }
733
734 #ifdef CONFIG_SOC_RESET_HOOK
soc_reset_hook(void)735 void soc_reset_hook(void)
736 {
737 SystemInit();
738
739 #if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)
740 Prepare_CM7(0);
741 #endif
742 }
743 #endif
744
745 #if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)
746
second_core_boot(void)747 static int second_core_boot(void)
748 {
749 /*
750 * RT1180 Specific CM7 Kick Off operation
751 */
752 /* Trigger S401 */
753 while ((MU_RT_S3MUA->TSR & MU_TSR_TE0_MASK) == 0) {
754 ; } /* Wait TR empty */
755 MU_RT_S3MUA->TR[0] = 0x17d20106;
756 while ((MU_RT_S3MUA->RSR & MU_RSR_RF0_MASK) == 0) {
757 ; } /* Wait RR Full */
758 while ((MU_RT_S3MUA->RSR & MU_RSR_RF1_MASK) == 0) {
759 ; } /* Wait RR Full */
760
761 /* Response from ELE must be always read */
762 __attribute__((unused)) volatile uint32_t result1, result2;
763 result1 = MU_RT_S3MUA->RR[0];
764 result2 = MU_RT_S3MUA->RR[1];
765
766 /* Deassert Wait */
767 BLK_CTRL_S_AONMIX->M7_CFG =
768 (BLK_CTRL_S_AONMIX->M7_CFG & (~BLK_CTRL_S_AONMIX_M7_CFG_WAIT_MASK)) |
769 BLK_CTRL_S_AONMIX_M7_CFG_WAIT(0);
770
771 return 0;
772 }
773
774 SYS_INIT(second_core_boot, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
775 #endif
776