1 /*
2  * Copyright 2022-2023, NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief System/hardware module for NXP RT5XX platform
10  *
11  * This module provides routines to initialize and support board-level
12  * hardware for the RT5XX platforms.
13  */
14 
15 #include <zephyr/init.h>
16 #include <zephyr/devicetree.h>
17 #include <zephyr/linker/sections.h>
18 #include <zephyr/logging/log.h>
19 #include <soc.h>
20 #include "fsl_power.h"
21 #include "fsl_clock.h"
22 #include <fsl_cache.h>
23 
24 LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL);
25 
26 #ifdef CONFIG_FLASH_MCUX_FLEXSPI_XIP
27 #include "flash_clock_setup.h"
28 #endif
29 
30 #if CONFIG_USB_DC_NXP_LPCIP3511
31 #include "usb_phy.h"
32 #include "usb.h"
33 #endif
34 
35 /* Board System oscillator settling time in us */
36 #define BOARD_SYSOSC_SETTLING_US 100U
37 /* Board xtal frequency in Hz */
38 #define BOARD_XTAL_SYS_CLK_HZ    24000000U
39 /* Core clock frequency: 198000000Hz */
40 #define CLOCK_INIT_CORE_CLOCK    198000000U
41 
42 #define CTIMER_CLOCK_SOURCE(node_id)                                                               \
43 	TO_CTIMER_CLOCK_SOURCE(DT_CLOCKS_CELL(node_id, name), DT_PROP(node_id, clk_source))
44 #define TO_CTIMER_CLOCK_SOURCE(inst, val) TO_CLOCK_ATTACH_ID(inst, val)
45 #define TO_CLOCK_ATTACH_ID(inst, val)     CLKCTL1_TUPLE_MUXA(CT32BIT##inst##FCLKSEL_OFFSET, val)
46 #define CTIMER_CLOCK_SETUP(node_id)       CLOCK_AttachClk(CTIMER_CLOCK_SOURCE(node_id));
47 
48 const clock_sys_pll_config_t g_sysPllConfig_clock_init = {
49 	/* OSC clock */
50 	.sys_pll_src = kCLOCK_SysPllXtalIn,
51 	/* Numerator of the SYSPLL0 fractional loop divider is 0 */
52 	.numerator = 0,
53 	/* Denominator of the SYSPLL0 fractional loop divider is 1 */
54 	.denominator = 1,
55 	/* Divide by 22 */
56 	.sys_pll_mult = kCLOCK_SysPllMult22};
57 
58 const clock_audio_pll_config_t g_audioPllConfig_clock_init = {
59 	/* OSC clock */
60 	.audio_pll_src = kCLOCK_AudioPllXtalIn,
61 	/* Numerator of the Audio PLL fractional loop divider is 0 */
62 	.numerator = 5040,
63 	/* Denominator of the Audio PLL fractional loop divider is 1 */
64 	.denominator = 27000,
65 	/* Divide by 22 */
66 	.audio_pll_mult = kCLOCK_AudioPllMult22};
67 
68 const clock_frg_clk_config_t g_frg0Config_clock_init = {
69 	.num = 0, .sfg_clock_src = kCLOCK_FrgPllDiv, .divider = 255U, .mult = 0};
70 
71 const clock_frg_clk_config_t g_frg12Config_clock_init = {
72 	.num = 12, .sfg_clock_src = kCLOCK_FrgMainClk, .divider = 255U, .mult = 167};
73 
74 #if CONFIG_USB_DC_NXP_LPCIP3511
75 /* USB PHY condfiguration */
76 #define BOARD_USB_PHY_D_CAL     (0x0CU)
77 #define BOARD_USB_PHY_TXCAL45DP (0x06U)
78 #define BOARD_USB_PHY_TXCAL45DM (0x06U)
79 #endif
80 
81 /* System clock frequency. */
82 extern uint32_t SystemCoreClock;
83 /* Main stack pointer */
84 extern char z_main_stack[];
85 
86 #ifdef CONFIG_NXP_IMXRT_BOOT_HEADER
87 extern char _flash_used[];
88 
89 extern void z_arm_reset(void);
90 extern void z_arm_nmi(void);
91 extern void z_arm_hard_fault(void);
92 extern void z_arm_mpu_fault(void);
93 extern void z_arm_bus_fault(void);
94 extern void z_arm_usage_fault(void);
95 extern void z_arm_secure_fault(void);
96 extern void z_arm_svc(void);
97 extern void z_arm_debug_monitor(void);
98 extern void z_arm_pendsv(void);
99 extern void sys_clock_isr(void);
100 extern void z_arm_exc_spurious(void);
101 
102 __imx_boot_ivt_section void (*const image_vector_table[])(void) = {
103 	(void (*)())(z_main_stack + CONFIG_MAIN_STACK_SIZE), /* 0x00 */
104 	z_arm_reset,                                         /* 0x04 */
105 	z_arm_nmi,                                           /* 0x08 */
106 	z_arm_hard_fault,                                    /* 0x0C */
107 	z_arm_mpu_fault,                                     /* 0x10 */
108 	z_arm_bus_fault,                                     /* 0x14 */
109 	z_arm_usage_fault,                                   /* 0x18 */
110 #if defined(CONFIG_ARM_SECURE_FIRMWARE)
111 	z_arm_secure_fault, /* 0x1C */
112 #else
113 	z_arm_exc_spurious,
114 #endif                                  /* CONFIG_ARM_SECURE_FIRMWARE */
115 	(void (*)())_flash_used,        /* 0x20, imageLength. */
116 	0,                              /* 0x24, imageType (Plain Image) */
117 	0,                              /* 0x28, authBlockOffset/crcChecksum */
118 	z_arm_svc,                      /* 0x2C */
119 	z_arm_debug_monitor,            /* 0x30 */
120 	(void (*)())image_vector_table, /* 0x34, imageLoadAddress. */
121 	z_arm_pendsv,                   /* 0x38 */
122 #if defined(CONFIG_SYS_CLOCK_EXISTS) && defined(CONFIG_CORTEX_M_SYSTICK_INSTALL_ISR)
123 	sys_clock_isr, /* 0x3C */
124 #else
125 	z_arm_exc_spurious,
126 #endif
127 };
128 #endif /* CONFIG_NXP_IMXRT_BOOT_HEADER */
129 
130 #if CONFIG_USB_DC_NXP_LPCIP3511
131 
usb_device_clock_init(void)132 static void usb_device_clock_init(void)
133 {
134 	uint8_t usbClockDiv = 1;
135 	uint32_t usbClockFreq;
136 	usb_phy_config_struct_t phyConfig = {
137 		BOARD_USB_PHY_D_CAL,
138 		BOARD_USB_PHY_TXCAL45DP,
139 		BOARD_USB_PHY_TXCAL45DM,
140 	};
141 
142 	/* Make sure USBHS ram buffer and usb1 phy has power up */
143 	POWER_DisablePD(kPDRUNCFG_APD_USBHS_SRAM);
144 	POWER_DisablePD(kPDRUNCFG_PPD_USBHS_SRAM);
145 	POWER_ApplyPD();
146 
147 	RESET_PeripheralReset(kUSBHS_PHY_RST_SHIFT_RSTn);
148 	RESET_PeripheralReset(kUSBHS_DEVICE_RST_SHIFT_RSTn);
149 	RESET_PeripheralReset(kUSBHS_HOST_RST_SHIFT_RSTn);
150 	RESET_PeripheralReset(kUSBHS_SRAM_RST_SHIFT_RSTn);
151 
152 	/* enable usb ip clock */
153 	CLOCK_EnableUsbHs0DeviceClock(kOSC_CLK_to_USB_CLK, usbClockDiv);
154 	/* save usb ip clock freq*/
155 	usbClockFreq = g_xtalFreq / usbClockDiv;
156 	CLOCK_SetClkDiv(kCLOCK_DivPfc1Clk, 4);
157 	/* enable usb ram clock */
158 	CLOCK_EnableClock(kCLOCK_UsbhsSram);
159 	/* enable USB PHY PLL clock, the phy bus clock (480MHz) source is same with USB IP */
160 	CLOCK_EnableUsbHs0PhyPllClock(kOSC_CLK_to_USB_CLK, usbClockFreq);
161 
162 	/* USB PHY initialization */
163 	USB_EhciPhyInit(kUSB_ControllerLpcIp3511Hs0, BOARD_XTAL_SYS_CLK_HZ, &phyConfig);
164 
165 #if defined(FSL_FEATURE_USBHSD_USB_RAM) && (FSL_FEATURE_USBHSD_USB_RAM)
166 	for (int i = 0; i < FSL_FEATURE_USBHSD_USB_RAM; i++) {
167 		((uint8_t *)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
168 	}
169 #endif
170 
171 	/* The following code should run after phy initialization and should wait
172 	 * some microseconds to make sure utmi clock valid
173 	 */
174 	/* enable usb1 host clock */
175 	CLOCK_EnableClock(kCLOCK_UsbhsHost);
176 	/*  Wait until host_needclk de-asserts */
177 	while (SYSCTL0->USB0CLKSTAT & SYSCTL0_USB0CLKSTAT_HOST_NEED_CLKST_MASK) {
178 		__ASM("nop");
179 	}
180 	/* According to reference mannual, device mode setting has to be set by access
181 	 * usb host register
182 	 */
183 	USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
184 	/* disable usb1 host clock */
185 	CLOCK_DisableClock(kCLOCK_UsbhsHost);
186 }
187 
188 #endif
189 
soc_reset_hook(void)190 void soc_reset_hook(void)
191 {
192 #ifndef CONFIG_NXP_IMXRT_BOOT_HEADER
193 	/*
194 	 * If boot did not proceed using a boot header, we should not assume
195 	 * the core is in reset state. Disable the MPU and correctly
196 	 * set the stack pointer, since we are about to push to
197 	 * the stack when we call SystemInit
198 	 */
199 	/* Clear stack limit registers */
200 	__set_MSPLIM(0);
201 	__set_PSPLIM(0);
202 	/* Disable MPU */
203 	MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
204 	/* Set stack pointer */
205 	__set_MSP((uint32_t)(z_main_stack + CONFIG_MAIN_STACK_SIZE));
206 #endif /* !CONFIG_NXP_IMXRT_BOOT_HEADER */
207 	/* This is provided by the SDK */
208 	SystemInit();
209 }
210 
211 /* Weak so that board can override with their own clock init routine. */
rt5xx_clock_init(void)212 void __weak rt5xx_clock_init(void)
213 {
214 	/* Configure LPOSC 1M */
215 	/* Power on LPOSC (1MHz) */
216 	POWER_DisablePD(kPDRUNCFG_PD_LPOSC);
217 	/* Wait until LPOSC stable */
218 	CLOCK_EnableLpOscClk();
219 
220 	/* Configure FRO clock source */
221 	/* Power on FRO (192MHz or 96MHz) */
222 	POWER_DisablePD(kPDRUNCFG_PD_FFRO);
223 	/* FRO_DIV1 is always enabled and used as Main clock during PLL update. */
224 	/* Enable all FRO outputs */
225 	CLOCK_EnableFroClk(kCLOCK_FroAllOutEn);
226 
227 #ifdef CONFIG_FLASH_MCUX_FLEXSPI_XIP
228 	/*
229 	 * Call function flexspi_clock_safe_config() to move FlexSPI clock to a stable
230 	 * clock source to avoid instruction/data fetch issue when updating PLL and Main
231 	 * clock if XIP(execute code on FLEXSPI memory).
232 	 */
233 	flexspi_clock_safe_config();
234 #endif
235 
236 	/* Let CPU run on FRO with divider 2 for safe switching. */
237 	CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 2);
238 	CLOCK_AttachClk(kFRO_DIV1_to_MAIN_CLK);
239 
240 	/* Configure SYSOSC clock source. */
241 	/* Power on SYSXTAL */
242 	POWER_DisablePD(kPDRUNCFG_PD_SYSXTAL);
243 	/* Updated XTAL oscillator settling time */
244 	POWER_UpdateOscSettlingTime(BOARD_SYSOSC_SETTLING_US);
245 	/* Enable system OSC */
246 	CLOCK_EnableSysOscClk(true, true, BOARD_SYSOSC_SETTLING_US);
247 	/* Sets external XTAL OSC freq */
248 	CLOCK_SetXtalFreq(BOARD_XTAL_SYS_CLK_HZ);
249 
250 	/* Configure SysPLL0 clock source. */
251 	CLOCK_InitSysPll(&g_sysPllConfig_clock_init);
252 	/* Enable MAIN PLL clock */
253 	CLOCK_InitSysPfd(kCLOCK_Pfd0, 24);
254 	/* Enable AUX0 PLL clock */
255 	CLOCK_InitSysPfd(kCLOCK_Pfd2, 24);
256 
257 	/* Configure Audio PLL clock source. */
258 	CLOCK_InitAudioPll(&g_audioPllConfig_clock_init);
259 	/* Enable Audio PLL clock */
260 	CLOCK_InitAudioPfd(kCLOCK_Pfd0, 26);
261 
262 	/* Set SYSCPUAHBCLKDIV divider to value 2 */
263 	CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 2U);
264 
265 	/* Setup FRG0 clock */
266 	CLOCK_SetFRGClock(&g_frg0Config_clock_init);
267 	/* Setup FRG12 clock */
268 	CLOCK_SetFRGClock(&g_frg12Config_clock_init);
269 
270 	/* Set up clock selectors - Attach clocks to the peripheries. */
271 	/* Switch MAIN_CLK to MAIN_PLL */
272 	CLOCK_AttachClk(kMAIN_PLL_to_MAIN_CLK);
273 	/* Switch SYSTICK_CLK to MAIN_CLK_DIV */
274 	CLOCK_AttachClk(kMAIN_CLK_DIV_to_SYSTICK_CLK);
275 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_usart, okay)
276 #ifdef CONFIG_FLEXCOMM0_CLK_SRC_FRG
277 	/* Switch FLEXCOMM0 to FRG */
278 	CLOCK_AttachClk(kFRG_to_FLEXCOMM0);
279 #elif defined(CONFIG_FLEXCOMM0_CLK_SRC_FRO)
280 	CLOCK_AttachClk(kFRO_DIV4_to_FLEXCOMM0);
281 #endif
282 #endif
283 #if CONFIG_USB_DC_NXP_LPCIP3511
284 	usb_device_clock_init();
285 #endif
286 
287 #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_i2s, okay) && CONFIG_I2S)
288 	/* attach AUDIO PLL clock to FLEXCOMM1 (I2S_PDM) */
289 	CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM0);
290 #endif
291 
292 #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm1), nxp_lpc_i2s, okay) && CONFIG_I2S)
293 	/* attach AUDIO PLL clock to FLEXCOMM1 (I2S1) */
294 	CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM1);
295 #endif
296 #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm3), nxp_lpc_i2s, okay) && CONFIG_I2S)
297 	/* attach AUDIO PLL clock to FLEXCOMM3 (I2S3) */
298 	CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM3);
299 #endif
300 
301 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm4), nxp_lpc_i2c, okay)
302 	/* Switch FLEXCOMM4 to FRO_DIV4 */
303 	CLOCK_AttachClk(kFRO_DIV4_to_FLEXCOMM4);
304 #endif
305 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(i3c0), nxp_mcux_i3c, okay)
306 	/* Attach main clock to I3C */
307 	CLOCK_AttachClk(kMAIN_CLK_to_I3C_CLK);
308 	CLOCK_AttachClk(kLPOSC_to_I3C_TC_CLK);
309 
310 	CLOCK_SetClkDiv(kCLOCK_DivI3cClk,
311 			DT_PROP(DT_NODELABEL(i3c0), clk_divider));
312 	CLOCK_SetClkDiv(kCLOCK_DivI3cSlowClk,
313 			DT_PROP(DT_NODELABEL(i3c0), clk_divider_slow));
314 	CLOCK_SetClkDiv(kCLOCK_DivI3cTcClk,
315 			DT_PROP(DT_NODELABEL(i3c0), clk_divider_tc));
316 #endif
317 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(hs_spi1), nxp_lpc_spi, okay)
318 	CLOCK_AttachClk(kFRO_DIV4_to_FLEXCOMM16);
319 #endif
320 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm12), nxp_lpc_usart, okay)
321 	/* Switch FLEXCOMM12 to FRG */
322 	CLOCK_AttachClk(kFRG_to_FLEXCOMM12);
323 #endif
324 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pmic_i2c), nxp_lpc_i2c, okay)
325 	CLOCK_AttachClk(kFRO_DIV4_to_FLEXCOMM15);
326 #endif
327 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lcdif), nxp_dcnano_lcdif, okay) && CONFIG_DISPLAY
328 	POWER_DisablePD(kPDRUNCFG_APD_DCNANO_SRAM);
329 	POWER_DisablePD(kPDRUNCFG_PPD_DCNANO_SRAM);
330 	POWER_ApplyPD();
331 
332 	CLOCK_AttachClk(kAUX0_PLL_to_DCPIXEL_CLK);
333 	/* Note- pixel clock follows formula
334 	 * (height + VSW + VFP + VBP) * (width + HSW + HFP + HBP) * frame rate.
335 	 * this means the clock divider will vary depending on
336 	 * the attached display.
337 	 *
338 	 * The root clock used here is the AUX0 PLL (PLL0 PFD2).
339 	 */
340 	CLOCK_SetClkDiv(
341 		kCLOCK_DivDcPixelClk,
342 		((CLOCK_GetSysPfdFreq(kCLOCK_Pfd2) /
343 		  DT_PROP(DT_CHILD(DT_NODELABEL(lcdif), display_timings), clock_frequency)) +
344 		 1));
345 
346 	CLOCK_EnableClock(kCLOCK_DisplayCtrl);
347 	RESET_ClearPeripheralReset(kDISP_CTRL_RST_SHIFT_RSTn);
348 
349 	CLOCK_EnableClock(kCLOCK_AxiSwitch);
350 	RESET_ClearPeripheralReset(kAXI_SWITCH_RST_SHIFT_RSTn);
351 #if defined(CONFIG_MEMC) && DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexspi2), nxp_imx_flexspi, okay)
352 	/* Enable write-through for FlexSPI1 space */
353 	CACHE64_POLSEL0->REG1_TOP = 0x27FFFC00U;
354 	CACHE64_POLSEL0->POLSEL = 0x11U;
355 #endif
356 #endif
357 
358 	/* Switch CLKOUT to FRO_DIV2 */
359 	CLOCK_AttachClk(kFRO_DIV2_to_CLKOUT);
360 
361 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usdhc0)) && CONFIG_IMX_USDHC
362 	/* Make sure USDHC ram buffer has been power up*/
363 	POWER_DisablePD(kPDRUNCFG_APD_USDHC0_SRAM);
364 	POWER_DisablePD(kPDRUNCFG_PPD_USDHC0_SRAM);
365 	POWER_DisablePD(kPDRUNCFG_PD_LPOSC);
366 	POWER_ApplyPD();
367 
368 	/* usdhc depend on 32K clock also */
369 	CLOCK_AttachClk(kLPOSC_DIV32_to_32KHZWAKE_CLK);
370 	CLOCK_AttachClk(kAUX0_PLL_to_SDIO0_CLK);
371 	CLOCK_SetClkDiv(kCLOCK_DivSdio0Clk, 1);
372 	CLOCK_EnableClock(kCLOCK_Sdio0);
373 	RESET_PeripheralReset(kSDIO0_RST_SHIFT_RSTn);
374 #endif
375 
376 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(smartdma)) && CONFIG_DMA_MCUX_SMARTDMA
377 	/* Power up SMARTDMA ram */
378 	POWER_DisablePD(kPDRUNCFG_APD_SMARTDMA_SRAM);
379 	POWER_DisablePD(kPDRUNCFG_PPD_SMARTDMA_SRAM);
380 	POWER_ApplyPD();
381 
382 	RESET_ClearPeripheralReset(kSMART_DMA_RST_SHIFT_RSTn);
383 	CLOCK_EnableClock(kCLOCK_Smartdma);
384 #endif
385 
386 	DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP)
387 
388 	/* Set up dividers. */
389 	/* Set AUDIOPLLCLKDIV divider to value 15 */
390 	CLOCK_SetClkDiv(kCLOCK_DivAudioPllClk, 15U);
391 	/* Set FRGPLLCLKDIV divider to value 11 */
392 	CLOCK_SetClkDiv(kCLOCK_DivPLLFRGClk, 11U);
393 	/* Set SYSTICKFCLKDIV divider to value 2 */
394 	CLOCK_SetClkDiv(kCLOCK_DivSystickClk, 2U);
395 	/* Set PFC0DIV divider to value 2 */
396 	CLOCK_SetClkDiv(kCLOCK_DivPfc0Clk, 2U);
397 	/* Set PFC1DIV divider to value 4 */
398 	CLOCK_SetClkDiv(kCLOCK_DivPfc1Clk, 4U);
399 	/* Set CLKOUTFCLKDIV divider to value 100 */
400 	CLOCK_SetClkDiv(kCLOCK_DivClockOut, 100U);
401 
402 #ifdef CONFIG_FLASH_MCUX_FLEXSPI_XIP
403 	/*
404 	 * Call function flexspi_setup_clock() to set user configured clock source/divider
405 	 * for FlexSPI.
406 	 */
407 	flexspi_setup_clock(FLEXSPI0, 0U, 2U);
408 #endif
409 
410 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexspi2), nxp_imx_flexspi, okay)
411 	/* Power up FlexSPI1 SRAM */
412 	POWER_DisablePD(kPDRUNCFG_APD_FLEXSPI1_SRAM);
413 	POWER_DisablePD(kPDRUNCFG_PPD_FLEXSPI1_SRAM);
414 	POWER_ApplyPD();
415 	/* Setup clock frequency for FlexSPI1 */
416 	CLOCK_AttachClk(kMAIN_CLK_to_FLEXSPI1_CLK);
417 	CLOCK_SetClkDiv(kCLOCK_DivFlexspi1Clk, 1);
418 	/* Reset peripheral module */
419 	RESET_PeripheralReset(kFLEXSPI1_RST_SHIFT_RSTn);
420 #endif
421 
422 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpadc0), nxp_lpc_lpadc, okay)
423 	SYSCTL0->PDRUNCFG0_CLR = SYSCTL0_PDRUNCFG0_ADC_PD_MASK;
424 	SYSCTL0->PDRUNCFG0_CLR = SYSCTL0_PDRUNCFG0_ADC_LP_MASK;
425 	RESET_PeripheralReset(kADC0_RST_SHIFT_RSTn);
426 	CLOCK_AttachClk(kFRO_DIV4_to_ADC_CLK);
427 	CLOCK_SetClkDiv(kCLOCK_DivAdcClk, 1);
428 #endif
429 
430 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(dmic0), nxp_dmic, okay)
431 	/* Using the Audio PLL as input clock leads to better clock dividers
432 	 * for typical PCM sample rates ({8,16,24,32,48,96} kHz.
433 	 */
434 	/* DMIC source from audio pll, divider 8, 24.576M/8=3.072MHZ
435 	 * Select Audio PLL as clock source. This should produce a bit clock
436 	 * of 3.072MHZ
437 	 */
438 	CLOCK_AttachClk(kAUDIO_PLL_to_DMIC);
439 	CLOCK_SetClkDiv(kCLOCK_DivDmicClk, 8);
440 
441 #endif
442 
443 	/* Set SystemCoreClock variable. */
444 	SystemCoreClock = CLOCK_INIT_CORE_CLOCK;
445 
446 	/* Set main clock to FRO as deep sleep clock by default. */
447 	POWER_SetDeepSleepClock(kDeepSleepClk_Fro);
448 
449 #if CONFIG_AUDIO_CODEC_WM8904
450 	/* attach AUDIO PLL clock to MCLK */
451 	CLOCK_AttachClk(kAUDIO_PLL_to_MCLK_CLK);
452 	CLOCK_SetClkDiv(kCLOCK_DivMclkClk, 1);
453 	SYSCTL1->MCLKPINDIR = SYSCTL1_MCLKPINDIR_MCLKPINDIR_MASK;
454 #endif
455 }
456 
457 #if CONFIG_MIPI_DSI
458 /* Weak so board can override this function */
imxrt_pre_init_display_interface(void)459 void __weak imxrt_pre_init_display_interface(void)
460 {
461 	/* Assert MIPI DPHY reset. */
462 	RESET_SetPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn);
463 	POWER_DisablePD(kPDRUNCFG_APD_MIPIDSI_SRAM);
464 	POWER_DisablePD(kPDRUNCFG_PPD_MIPIDSI_SRAM);
465 	POWER_DisablePD(kPDRUNCFG_PD_MIPIDSI);
466 	POWER_ApplyPD();
467 
468 	/* RxClkEsc max 60MHz, TxClkEsc 12 to 20MHz. */
469 	CLOCK_AttachClk(kFRO_DIV1_to_MIPI_DPHYESC_CLK);
470 	/* RxClkEsc = 192MHz / 4 = 48MHz. */
471 	CLOCK_SetClkDiv(kCLOCK_DivDphyEscRxClk, 4);
472 	/* TxClkEsc = 192MHz / 4 / 3 = 16MHz. */
473 	CLOCK_SetClkDiv(kCLOCK_DivDphyEscTxClk, 3);
474 
475 	/*
476 	 * The DPHY bit clock must be fast enough to send out the pixels,
477 	 * it should be larger than:
478 	 *
479 	 *     (Pixel clock * bit per output pixel) / number of MIPI data lane
480 	 *
481 	 * DPHY supports up to 895.1MHz bit clock.
482 	 * We set the divider of the PFD3 output of the SYSPLL, which has a
483 	 * fixed multiplied of 18, and use this output frequency for the DPHY.
484 	 */
485 
486 #ifdef CONFIG_MIPI_DPHY_CLK_SRC_AUX1_PLL
487 	/* Note: AUX1 PLL clock is system pll clock * 18 / pfd.
488 	 * system pll clock is configured at 528MHz by default.
489 	 */
490 	CLOCK_AttachClk(kAUX1_PLL_to_MIPI_DPHY_CLK);
491 	CLOCK_InitSysPfd(kCLOCK_Pfd3,
492 			 ((CLOCK_GetSysPllFreq() * 18ull) /
493 			  ((unsigned long long)(DT_PROP(DT_NODELABEL(mipi_dsi), phy_clock)))));
494 	CLOCK_SetClkDiv(kCLOCK_DivDphyClk, 1);
495 #elif defined(CONFIG_MIPI_DPHY_CLK_SRC_FRO)
496 	CLOCK_AttachClk(kFRO_DIV1_to_MIPI_DPHY_CLK);
497 	CLOCK_SetClkDiv(kCLOCK_DivDphyClk,
498 			(CLK_FRO_CLK / DT_PROP(DT_NODELABEL(mipi_dsi), phy_clock)));
499 #endif
500 	/* Clear DSI control reset (Note that DPHY reset is cleared later)*/
501 	RESET_ClearPeripheralReset(kMIPI_DSI_CTRL_RST_SHIFT_RSTn);
502 }
503 
imxrt_post_init_display_interface(void)504 void __weak imxrt_post_init_display_interface(void)
505 {
506 	/* Deassert MIPI DPHY reset. */
507 	RESET_ClearPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn);
508 }
509 
imxrt_deinit_display_interface(void)510 void __weak imxrt_deinit_display_interface(void)
511 {
512 	/* Assert MIPI DPHY and DSI reset */
513 	RESET_SetPeripheralReset(kMIPI_DSI_PHY_RST_SHIFT_RSTn);
514 	RESET_SetPeripheralReset(kMIPI_DSI_CTRL_RST_SHIFT_RSTn);
515 	/* Remove clock from DPHY */
516 	CLOCK_AttachClk(kNONE_to_MIPI_DPHY_CLK);
517 }
518 
519 #endif
520 
521 extern void rt5xx_power_init(void);
522 
523 /**
524  *
525  * @brief Perform basic hardware initialization
526  *
527  * Initialize the interrupt controller device drivers.
528  * Also initialize the timer device driver, if required.
529  */
soc_early_init_hook(void)530 void soc_early_init_hook(void)
531 {
532 	/* Initialize clocks with tool generated code */
533 	rt5xx_clock_init();
534 
535 #ifndef CONFIG_IMXRT5XX_CODE_CACHE
536 	CACHE64_DisableCache(CACHE64_CTRL0);
537 #endif
538 
539 	/* Some ROM versions may have errata leaving these pins in a non-reset state,
540 	 * which can often cause power leakage on most expected board designs,
541 	 * restore the reset state here and leave the pin configuration up to board/user DT
542 	 */
543 	IOPCTL->PIO[1][15] = 0;
544 	IOPCTL->PIO[3][28] = 0;
545 	IOPCTL->PIO[3][29] = 0;
546 #ifdef CONFIG_PM
547 	rt5xx_power_init();
548 #endif
549 
550 }
551