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