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 | /* * Copyright 2022-2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/arch/cpu.h> #include <zephyr/device.h> #include <zephyr/drivers/uart.h> #include <zephyr/init.h> #include <zephyr/kernel.h> #include <zephyr/linker/sections.h> #include <zephyr/sys/util_macro.h> #include <cortex_m/exception.h> #include <fsl_power.h> #include <fsl_clock.h> #include <fsl_common.h> #include <fsl_device_registers.h> #include "soc.h" #include "flexspi_clock_setup.h" #include "fsl_ocotp.h" #ifdef CONFIG_NXP_RW6XX_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) && defined(CONFIG_CORTEX_M_SYSTICK_INSTALL_ISR) sys_clock_isr, /* 0x3C */ #else z_arm_exc_spurious, #endif }; #endif /* CONFIG_NXP_RW6XX_BOOT_HEADER */ const clock_avpll_config_t avpll_config = { .ch1Freq = kCLOCK_AvPllChFreq12p288m, .ch2Freq = kCLOCK_AvPllChFreq64m, .enableCali = true }; /** * @brief Initialize the system clocks and peripheral clocks * * This function is called from the power management code as the * clock needs to be re-initialized on exit from Standby mode. Hence * this function is relocated to RAM. */ __ramfunc void clock_init(void) { POWER_DisableGDetVSensors(); if ((PMU->CAU_SLP_CTRL & PMU_CAU_SLP_CTRL_SOC_SLP_RDY_MASK) == 0U) { /* LPOSC not enabled, enable it */ CLOCK_EnableClock(kCLOCK_RefClkCauSlp); } if ((SYSCTL2->SOURCE_CLK_GATE & SYSCTL2_SOURCE_CLK_GATE_REFCLK_SYS_CG_MASK) != 0U) { /* REFCLK_SYS not enabled, enable it */ CLOCK_EnableClock(kCLOCK_RefClkSys); } /* Initialize T3 clocks and t3pll_mci_48_60m_irc configured to 48.3MHz */ CLOCK_InitT3RefClk(kCLOCK_T3MciIrc48m); /* Enable FFRO */ CLOCK_EnableClock(kCLOCK_T3PllMciIrcClk); /* Enable T3 256M clock and SFRO */ CLOCK_EnableClock(kCLOCK_T3PllMci256mClk); /* Move FLEXSPI clock source to T3 256m / 4 to avoid instruction/data fetch issue in XIP * when updating PLL and main clock. */ set_flexspi_clock(FLEXSPI, 6U, 4U); /* First let M33 run on SOSC */ CLOCK_AttachClk(kSYSOSC_to_MAIN_CLK); CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 1); /* tcpu_mci_clk configured to 260MHz, tcpu_mci_flexspi_clk 312MHz. */ CLOCK_InitTcpuRefClk(3120000000UL, kCLOCK_TcpuFlexspiDiv10); /* Enable tcpu_mci_clk 260MHz. Keep tcpu_mci_flexspi_clk gated. */ CLOCK_EnableClock(kCLOCK_TcpuMciClk); /* tddr_mci_flexspi_clk 320MHz */ CLOCK_InitTddrRefClk(kCLOCK_TddrFlexspiDiv10); CLOCK_EnableClock(kCLOCK_TddrMciFlexspiClk); /* 320MHz */ /* Enable AUX0 PLL to 260 MHz */ CLOCK_SetClkDiv(kCLOCK_DivAux0PllClk, 1U); /* Init AVPLL and enable both channels */ CLOCK_InitAvPll(&avpll_config); CLOCK_SetClkDiv(kCLOCK_DivAudioPllClk, 1U); /* Configure MainPll to 260MHz, then let CM33 run on Main PLL. */ CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 1U); CLOCK_SetClkDiv(kCLOCK_DivMainPllClk, 1U); CLOCK_AttachClk(kMAIN_PLL_to_MAIN_CLK); /* Set SYSTICKFCLKDIV divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivSystickClk, 1U); CLOCK_AttachClk(kSYSTICK_DIV_to_SYSTICK_CLK); /* Set PLL FRG clock to 20MHz. */ CLOCK_SetClkDiv(kCLOCK_DivPllFrgClk, 13U); /* Call function set_flexspi_clock() to set flexspi clock source to aux0_pll_clk in XIP. */ set_flexspi_clock(FLEXSPI, 2U, 2U); #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(os_timer), nxp_os_timer, okay) CLOCK_AttachClk(kLPOSC_to_OSTIMER_CLK); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(wwdt), 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 defined(CONFIG_ADC_MCUX_GAU) || defined(CONFIG_DAC_MCUX_GAU) /* Attack clock for GAU and reset */ CLOCK_AttachClk(kMAIN_CLK_to_GAU_CLK); CLOCK_SetClkDiv(kCLOCK_DivGauClk, 1U); CLOCK_EnableClock(kCLOCK_Gau); RESET_PeripheralReset(kGAU_RST_SHIFT_RSTn); #endif /* GAU */ /* Any flexcomm can be USART */ #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_usart, okay)) && CONFIG_SERIAL CLOCK_SetFRGClock(&(const clock_frg_clk_config_t){0, kCLOCK_FrgPllDiv, 255, 0}); CLOCK_AttachClk(kFRG_to_FLEXCOMM0); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm1), nxp_lpc_usart, okay)) && CONFIG_SERIAL CLOCK_SetFRGClock(&(const clock_frg_clk_config_t){1, kCLOCK_FrgPllDiv, 255, 0}); CLOCK_AttachClk(kFRG_to_FLEXCOMM1); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm2), nxp_lpc_usart, okay)) && CONFIG_SERIAL CLOCK_SetFRGClock(&(const clock_frg_clk_config_t){2, kCLOCK_FrgPllDiv, 255, 0}); CLOCK_AttachClk(kFRG_to_FLEXCOMM2); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm3), nxp_lpc_usart, okay)) && CONFIG_SERIAL CLOCK_SetFRGClock(&(const clock_frg_clk_config_t){3, kCLOCK_FrgPllDiv, 255, 0}); CLOCK_AttachClk(kFRG_to_FLEXCOMM3); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm14), nxp_lpc_usart, okay)) && CONFIG_SERIAL CLOCK_SetFRGClock(&(const clock_frg_clk_config_t){14, kCLOCK_FrgPllDiv, 255, 0}); CLOCK_AttachClk(kFRG_to_FLEXCOMM14); #endif /* Any flexcomm can be I2C */ #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_i2c, okay)) && CONFIG_I2C CLOCK_AttachClk(kSFRO_to_FLEXCOMM0); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm1), nxp_lpc_i2c, okay)) && CONFIG_I2C CLOCK_AttachClk(kSFRO_to_FLEXCOMM1); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm2), nxp_lpc_i2c, okay)) && CONFIG_I2C CLOCK_AttachClk(kSFRO_to_FLEXCOMM2); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm3), nxp_lpc_i2c, okay)) && CONFIG_I2C CLOCK_AttachClk(kSFRO_to_FLEXCOMM3); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm14), nxp_lpc_i2c, okay)) && CONFIG_I2C CLOCK_AttachClk(kSFRO_to_FLEXCOMM14); #endif /* Clock flexcomms when used as SPI */ #ifdef CONFIG_SPI #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm0), nxp_lpc_spi, okay)) /* Set up Flexcomm0 FRG to clock at 260 MHz from main clock */ const clock_frg_clk_config_t flexcomm0_frg = {0, kCLOCK_FrgMainClk, 255, 0}; CLOCK_SetFRGClock(&flexcomm0_frg); CLOCK_AttachClk(kFRG_to_FLEXCOMM0); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm1), nxp_lpc_spi, okay)) CLOCK_AttachClk(kSFRO_to_FLEXCOMM1); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm2), nxp_lpc_spi, okay)) CLOCK_AttachClk(kSFRO_to_FLEXCOMM2); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm3), nxp_lpc_spi, okay)) CLOCK_AttachClk(kSFRO_to_FLEXCOMM3); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm14), nxp_lpc_spi, okay)) CLOCK_AttachClk(kSFRO_to_FLEXCOMM14); #endif #endif /* CONFIG_SPI */ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dmic0)) && CONFIG_AUDIO_DMIC_MCUX /* Clock DMIC from Audio PLL. PLL output is sourced from AVPLL * channel 1, which is clocked at 12.288 MHz. We can divide this * by 4 to achieve the desired DMIC bit clk of 3.072 MHz */ CLOCK_AttachClk(kAUDIO_PLL_to_DMIC_CLK); CLOCK_SetClkDiv(kCLOCK_DivDmicClk, 4); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lcdic)) && CONFIG_MIPI_DBI_NXP_LCDIC CLOCK_AttachClk(kMAIN_CLK_to_LCD_CLK); RESET_PeripheralReset(kLCDIC_RST_SHIFT_RSTn); #endif #ifdef CONFIG_COUNTER_MCUX_CTIMER #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ctimer0), nxp_lpc_ctimer, okay)) CLOCK_AttachClk(kSFRO_to_CTIMER0); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ctimer1), nxp_lpc_ctimer, okay)) CLOCK_AttachClk(kSFRO_to_CTIMER1); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ctimer2), nxp_lpc_ctimer, okay)) CLOCK_AttachClk(kSFRO_to_CTIMER2); #endif #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ctimer3), nxp_lpc_ctimer, okay)) CLOCK_AttachClk(kSFRO_to_CTIMER3); #endif #endif /* CONFIG_COUNTER_MCUX_CTIMER */ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb_otg)) && CONFIG_USB_DC_NXP_EHCI /* Enable system xtal from Analog */ SYSCTL2->ANA_GRP_CTRL |= SYSCTL2_ANA_GRP_CTRL_PU_AG_MASK; /* reset USB */ RESET_PeripheralReset(kUSB_RST_SHIFT_RSTn); /* enable usb clock */ CLOCK_EnableClock(kCLOCK_Usb); /* enable usb phy clock */ CLOCK_EnableUsbhsPhyClock(); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(enet)) && CONFIG_NET_L2_ETHERNET RESET_PeripheralReset(kENET_IPG_RST_SHIFT_RSTn); RESET_PeripheralReset(kENET_IPG_S_RST_SHIFT_RSTn); #endif } extern void nxp_rw6xx_power_init(void); /** * * @brief Perform basic hardware initialization * * Initialize the interrupt controller device drivers. * Also initialize the timer device driver, if required. */ void soc_early_init_hook(void) { #if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(wwdt), nxp_lpc_wwdt, okay)) POWER_EnableResetSource(kPOWER_ResetSourceWdt); #endif #if DT_NODE_HAS_PROP(DT_NODELABEL(pmu), reset_causes_en) #define PMU_RESET_CAUSES_ \ DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(pmu), reset_causes_en, DT_PROP_BY_IDX, (|)) #define PMU_RESET_CAUSES \ COND_CODE_0(IS_EMPTY(PMU_RESET_CAUSES_), (PMU_RESET_CAUSES_), (0)) #define WDT_RESET \ COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(wwdt), (kPOWER_ResetSourceWdt), (0)) #define RESET_CAUSES \ (PMU_RESET_CAUSES | WDT_RESET) #else #define RESET_CAUSES 0 #endif POWER_EnableResetSource(RESET_CAUSES); /* Initialize clock */ clock_init(); #if defined(CONFIG_ADC_MCUX_GAU) || defined(CONFIG_DAC_MCUX_GAU) POWER_PowerOnGau(); #endif #if CONFIG_PM nxp_rw6xx_power_init(); #endif } void soc_reset_hook(void) { /* This is provided by the SDK */ SystemInit(); } |