Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | /* * Copyright (c) 2020, NXP * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief System/hardware module for nxp_lpc55s69 platform * * This module provides routines to initialize and support board-level * hardware for the nxp_lpc55s69 platform. */ #include <kernel.h> #include <device.h> #include <init.h> #include <soc.h> #include <drivers/uart.h> #include <linker/sections.h> #include <arch/cpu.h> #include <aarch32/cortex_m/exc.h> #include <fsl_power.h> #include <fsl_clock.h> #include <fsl_common.h> #include <fsl_device_registers.h> #if CONFIG_USB_DC_NXP_LPCIP3511 #include "usb_phy.h" #include "usb_dc_mcux.h" #endif #define SYSTEM_IS_XIP_FLEXSPI() \ ((((uint32_t)nxp_rt600_init >= 0x08000000U) && \ ((uint32_t)nxp_rt600_init < 0x10000000U)) || \ (((uint32_t)nxp_rt600_init >= 0x18000000U) && \ ((uint32_t)nxp_rt600_init < 0x20000000U))) #define CTIMER_CLOCK_SOURCE(node_id) \ TO_CTIMER_CLOCK_SOURCE(DT_CLOCKS_CELL(node_id, name), DT_PROP(node_id, clk_source)) #define TO_CTIMER_CLOCK_SOURCE(inst, val) TO_CLOCK_ATTACH_ID(inst, val) #define TO_CLOCK_ATTACH_ID(inst, val) CLKCTL1_TUPLE_MUXA(CT32BIT##inst##FCLKSEL_OFFSET, val) #define CTIMER_CLOCK_SETUP(node_id) CLOCK_AttachClk(CTIMER_CLOCK_SOURCE(node_id)); #ifdef CONFIG_INIT_SYS_PLL const clock_sys_pll_config_t g_sysPllConfig = { .sys_pll_src = kCLOCK_SysPllXtalIn, .numerator = 0, .denominator = 1, .sys_pll_mult = kCLOCK_SysPllMult22 }; #endif #ifdef CONFIG_INIT_AUDIO_PLL const clock_audio_pll_config_t g_audioPllConfig = { .audio_pll_src = kCLOCK_AudioPllXtalIn, .numerator = 5040, .denominator = 27000, .audio_pll_mult = kCLOCK_AudioPllMult22 }; #endif #if CONFIG_USB_DC_NXP_LPCIP3511 /* USB PHY condfiguration */ #define BOARD_USB_PHY_D_CAL (0x0CU) #define BOARD_USB_PHY_TXCAL45DP (0x06U) #define BOARD_USB_PHY_TXCAL45DM (0x06U) #endif #ifdef CONFIG_NXP_IMX_RT6XX_BOOT_HEADER extern char z_main_stack[]; extern char _flash_used[]; extern void z_arm_reset(void); extern void z_arm_nmi(void); extern void z_arm_hard_fault(void); extern void z_arm_mpu_fault(void); extern void z_arm_bus_fault(void); extern void z_arm_usage_fault(void); extern void z_arm_secure_fault(void); extern void z_arm_svc(void); extern void z_arm_debug_monitor(void); extern void z_arm_pendsv(void); extern void sys_clock_isr(void); extern void z_arm_exc_spurious(void); __imx_boot_ivt_section void (* const image_vector_table[])(void) = { (void (*)())(z_main_stack + CONFIG_MAIN_STACK_SIZE), /* 0x00 */ z_arm_reset, /* 0x04 */ z_arm_nmi, /* 0x08 */ z_arm_hard_fault, /* 0x0C */ z_arm_mpu_fault, /* 0x10 */ z_arm_bus_fault, /* 0x14 */ z_arm_usage_fault, /* 0x18 */ #if defined(CONFIG_ARM_SECURE_FIRMWARE) z_arm_secure_fault, /* 0x1C */ #else z_arm_exc_spurious, #endif /* CONFIG_ARM_SECURE_FIRMWARE */ (void (*)())_flash_used, /* 0x20, imageLength. */ 0, /* 0x24, imageType (Plain Image) */ 0, /* 0x28, authBlockOffset/crcChecksum */ z_arm_svc, /* 0x2C */ z_arm_debug_monitor, /* 0x30 */ (void (*)())image_vector_table, /* 0x34, imageLoadAddress. */ z_arm_pendsv, /* 0x38 */ #if defined(CONFIG_SYS_CLOCK_EXISTS) sys_clock_isr, /* 0x3C */ #else z_arm_exc_spurious, #endif }; #endif /* CONFIG_NXP_IMX_RT6XX_BOOT_HEADER */ #if CONFIG_USB_DC_NXP_LPCIP3511 static void usb_device_clock_init(void) { uint8_t usbClockDiv = 1; uint32_t usbClockFreq; usb_phy_config_struct_t phyConfig = { BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM, }; /* enable USB IP clock */ CLOCK_SetClkDiv(kCLOCK_DivPfc1Clk, 5); CLOCK_AttachClk(kXTALIN_CLK_to_USB_CLK); CLOCK_SetClkDiv(kCLOCK_DivUsbHsFclk, usbClockDiv); CLOCK_EnableUsbhsDeviceClock(); RESET_PeripheralReset(kUSBHS_PHY_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSBHS_DEVICE_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSBHS_HOST_RST_SHIFT_RSTn); RESET_PeripheralReset(kUSBHS_SRAM_RST_SHIFT_RSTn); /*Make sure USDHC ram buffer has power up*/ POWER_DisablePD(kPDRUNCFG_APD_USBHS_SRAM); POWER_DisablePD(kPDRUNCFG_PPD_USBHS_SRAM); POWER_ApplyPD(); /* save usb ip clock freq*/ usbClockFreq = g_xtalFreq / usbClockDiv; /* enable USB PHY PLL clock, the phy bus clock (480MHz) source is same with USB IP */ CLOCK_EnableUsbHs0PhyPllClock(kXTALIN_CLK_to_USB_CLK, usbClockFreq); #if defined(FSL_FEATURE_USBHSD_USB_RAM) && (FSL_FEATURE_USBHSD_USB_RAM) for (int i = 0; i < FSL_FEATURE_USBHSD_USB_RAM; i++) { ((uint8_t *)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)[i] = 0x00U; } #endif USB_EhciPhyInit(kUSB_ControllerLpcIp3511Hs0, CLK_XTAL_OSC_CLK, &phyConfig); /* the following code should run after phy initialization and * should wait some microseconds to make sure utmi clock valid */ /* enable usb1 host clock */ CLOCK_EnableClock(kCLOCK_UsbhsHost); /* Wait until host_needclk de-asserts */ while (SYSCTL0->USBCLKSTAT & SYSCTL0_USBCLKSTAT_HOST_NEED_CLKST_MASK) { __ASM("nop"); } /* According to reference mannual, device mode setting has to be set by * access usb host register */ USBHSH->PORTMODE |= USBHSH_PORTMODE_DEV_ENABLE_MASK; /* disable usb1 host clock */ CLOCK_DisableClock(kCLOCK_UsbhsHost); } #endif /** * * @brief Initialize the system clock * * @return N/A * */ static ALWAYS_INLINE void clock_init(void) { #ifdef CONFIG_SOC_MIMXRT685S_CM33 /* Configure LPOSC clock*/ POWER_DisablePD(kPDRUNCFG_PD_LPOSC); /* Configure FFRO clock */ POWER_DisablePD(kPDRUNCFG_PD_FFRO); CLOCK_EnableFfroClk(kCLOCK_Ffro48M); /* Configure SFRO clock */ POWER_DisablePD(kPDRUNCFG_PD_SFRO); CLOCK_EnableSfroClk(); /* Let CPU run on FFRO for safe switching. */ CLOCK_AttachClk(kFFRO_to_MAIN_CLK); /* Configure SYSOSC clock source */ POWER_DisablePD(kPDRUNCFG_PD_SYSXTAL); POWER_UpdateOscSettlingTime(CONFIG_SYSOSC_SETTLING_US); CLOCK_EnableSysOscClk(true, true, CONFIG_SYSOSC_SETTLING_US); CLOCK_SetXtalFreq(CONFIG_XTAL_SYS_CLK_HZ); #ifdef CONFIG_INIT_SYS_PLL /* Configure SysPLL0 clock source */ CLOCK_InitSysPll(&g_sysPllConfig); CLOCK_InitSysPfd(kCLOCK_Pfd0, 19); CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); #endif #ifdef CONFIG_INIT_AUDIO_PLL /* Configure Audio PLL clock source */ CLOCK_InitAudioPll(&g_audioPllConfig); CLOCK_InitAudioPfd(kCLOCK_Pfd0, 26); CLOCK_SetClkDiv(kCLOCK_DivAudioPllClk, 15U); #endif /* Set SYSCPUAHBCLKDIV divider to value 2 */ CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 2U); /* Set up clock selectors - Attach clocks to the peripheries */ CLOCK_AttachClk(kMAIN_PLL_to_MAIN_CLK); /* Set up dividers */ /* Set PFC0DIV divider to value 2 */ CLOCK_SetClkDiv(kCLOCK_DivPfc0Clk, 2U); /* Set FRGPLLCLKDIV divider to value 12 */ CLOCK_SetClkDiv(kCLOCK_DivPllFrgClk, 12U); CLOCK_AttachClk(kSFRO_to_FLEXCOMM0); #if CONFIG_USB_DC_NXP_LPCIP3511 usb_device_clock_init(); #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm2), nxp_lpc_i2c, okay) CLOCK_AttachClk(kSFRO_to_FLEXCOMM2); #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm4), nxp_lpc_usart, okay) CLOCK_AttachClk(kSFRO_to_FLEXCOMM4); #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm5), nxp_lpc_spi, okay) CLOCK_AttachClk(kFFRO_to_FLEXCOMM5); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm1), nxp_lpc_i2s, okay)) /* attach AUDIO PLL clock to FLEXCOMM1 (I2S1) */ CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM1); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm3), nxp_lpc_i2s, okay)) /* attach AUDIO PLL clock to FLEXCOMM3 (I2S3) */ CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM3); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(wwdt0), nxp_lpc_wwdt, okay)) CLOCK_AttachClk(kLPOSC_to_WDT0_CLK); #else /* Allowed to select none if not being used for watchdog to * reduce power */ CLOCK_AttachClk(kNONE_to_WDT0_CLK); #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc1), okay) && CONFIG_DISK_DRIVER_SDMMC /* Make sure USDHC ram buffer has been power up*/ POWER_DisablePD(kPDRUNCFG_APD_USDHC0_SRAM); POWER_DisablePD(kPDRUNCFG_PPD_USDHC0_SRAM); POWER_DisablePD(kPDRUNCFG_PD_LPOSC); POWER_ApplyPD(); /* usdhc depend on 32K clock also */ CLOCK_AttachClk(kLPOSC_DIV32_to_32KHZWAKE_CLK); CLOCK_AttachClk(kAUX0_PLL_to_SDIO0_CLK); CLOCK_SetClkDiv(kCLOCK_DivSdio0Clk, 1); CLOCK_EnableClock(kCLOCK_Sdio0); RESET_PeripheralReset(kSDIO0_RST_SHIFT_RSTn); #endif DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) #endif /* CONFIG_SOC_MIMXRT685S_CM33 */ } #if (DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc1), okay) && CONFIG_DISK_DRIVER_SDMMC) void imxrt_usdhc_pinmux(uint16_t nusdhc, bool init, uint32_t speed, uint32_t strength) { } #endif /** * * @brief Perform basic hardware initialization * * Initialize the interrupt controller device drivers. * Also initialize the timer device driver, if required. * * @return 0 */ static int nxp_rt600_init(const struct device *arg) { ARG_UNUSED(arg); /* old interrupt lock level */ unsigned int oldLevel; /* disable interrupts */ oldLevel = irq_lock(); /* Enable cache to accelerate boot. */ if (SYSTEM_IS_XIP_FLEXSPI() && (CACHE64_POLSEL->POLSEL == 0)) { /* * Set command to invalidate all ways and write GO bit * to initiate command */ CACHE64->CCR = (CACHE64_CTRL_CCR_INVW1_MASK | CACHE64_CTRL_CCR_INVW0_MASK); CACHE64->CCR |= CACHE64_CTRL_CCR_GO_MASK; /* Wait until the command completes */ while (CACHE64->CCR & CACHE64_CTRL_CCR_GO_MASK) { } /* Enable cache, enable write buffer */ CACHE64->CCR = (CACHE64_CTRL_CCR_ENWRBUF_MASK | CACHE64_CTRL_CCR_ENCACHE_MASK); /* Set whole FlexSPI0 space to write through. */ CACHE64_POLSEL->REG0_TOP = 0x07FFFC00U; CACHE64_POLSEL->REG1_TOP = 0x0U; CACHE64_POLSEL->POLSEL = 0x1U; __ISB(); __DSB(); } /* Initialize clock */ clock_init(); /* * install default handler that simply resets the CPU if configured in * the kernel, NOP otherwise */ NMI_INIT(); /* restore interrupt state */ irq_unlock(oldLevel); return 0; } SYS_INIT(nxp_rt600_init, PRE_KERNEL_1, 0); |