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