diff --git a/soc/nxp/imxrt/CMakeLists.txt b/soc/nxp/imxrt/CMakeLists.txt index ac5302a32fc..5984d081ba9 100644 --- a/soc/nxp/imxrt/CMakeLists.txt +++ b/soc/nxp/imxrt/CMakeLists.txt @@ -39,6 +39,9 @@ if(CONFIG_SOC_SERIES_IMXRT10XX OR CONFIG_SOC_SERIES_IMXRT11XX) endif() if(CONFIG_SOC_SERIES_IMXRT118X) + if(CONFIG_SOC_MIMXRT1189_CM7) + zephyr_sources(mpu_regions.c) + endif() if(CONFIG_EXTERNAL_MEM_CONFIG_DATA) set(boot_hdr_xmcd_data_section ".boot_hdr.xmcd_data") endif() diff --git a/soc/nxp/imxrt/imxrt118x/CMakeLists.txt b/soc/nxp/imxrt/imxrt118x/CMakeLists.txt index da554b97e75..faabf48236f 100644 --- a/soc/nxp/imxrt/imxrt118x/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt118x/CMakeLists.txt @@ -13,4 +13,11 @@ endif() zephyr_include_directories(.) +if(CONFIG_MEMC_MCUX_FLEXSPI) + zephyr_sources(flexspi.c) + if(CONFIG_FLASH_MCUX_FLEXSPI_XIP) + zephyr_code_relocate(FILES flexspi.c LOCATION ${CONFIG_FLASH_MCUX_FLEXSPI_XIP_MEM}_TEXT) + endif() +endif() + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/imxrt/imxrt118x/Kconfig b/soc/nxp/imxrt/imxrt118x/Kconfig index c8bcbee4ea0..b2aa59090af 100644 --- a/soc/nxp/imxrt/imxrt118x/Kconfig +++ b/soc/nxp/imxrt/imxrt118x/Kconfig @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 config SOC_SERIES_IMXRT118X + select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS if SOC_MIMXRT1189_CM7 select CPU_CORTEX_M_HAS_DWT select SOC_RESET_HOOK select INIT_ARCH_HW_AT_BOOT if SOC_MIMXRT1189_CM33 diff --git a/soc/nxp/imxrt/imxrt118x/flexspi.c b/soc/nxp/imxrt/imxrt118x/flexspi.c new file mode 100644 index 00000000000..b8b49a8f4aa --- /dev/null +++ b/soc/nxp/imxrt/imxrt118x/flexspi.c @@ -0,0 +1,65 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +uint32_t flexspi_clock_set_freq(uint32_t clock_name, uint32_t rate) +{ + clock_name_t root; + uint32_t root_rate; + FLEXSPI_Type *flexspi; + clock_root_t flexspi_clk; + clock_ip_name_t clk_gate; + uint32_t divider; + + switch (clock_name) { + case IMX_CCM_FLEXSPI_CLK: + flexspi_clk = kCLOCK_Root_Flexspi1; + flexspi = (FLEXSPI_Type *)DT_REG_ADDR(DT_NODELABEL(flexspi)); + clk_gate = kCLOCK_Flexspi1; + break; + case IMX_CCM_FLEXSPI2_CLK: + flexspi_clk = kCLOCK_Root_Flexspi2; + flexspi = (FLEXSPI_Type *)DT_REG_ADDR(DT_NODELABEL(flexspi2)); + clk_gate = kCLOCK_Flexspi2; + break; + default: + return -ENOTSUP; + } + root = CLOCK_GetRootClockSource(flexspi_clk, + CLOCK_GetRootClockMux(flexspi_clk)); + /* Get clock root frequency */ + root_rate = CLOCK_GetFreq(root); + /* Select a divider based on root clock frequency. We round the + * divider up, so that the resulting clock frequency is lower than + * requested when we can't output the exact requested frequency + */ + divider = ((root_rate + (rate - 1)) / rate); + /* Cap divider to max value */ + divider = MIN(divider, CCM_CLOCK_ROOT_CONTROL_DIV_MASK); + + while (FLEXSPI_GetBusIdleStatus(flexspi) == false) { + /* Spin */ + } + FLEXSPI_Enable(flexspi, false); + + CLOCK_DisableClock(clk_gate); + + CLOCK_SetRootClockDiv(flexspi_clk, divider); + + CLOCK_EnableClock(clk_gate); + + FLEXSPI_Enable(flexspi, true); + + FLEXSPI_SoftwareReset(flexspi); + + return 0; +} diff --git a/soc/nxp/imxrt/imxrt118x/soc.c b/soc/nxp/imxrt/imxrt118x/soc.c index f170b941840..fa4d3079c3b 100644 --- a/soc/nxp/imxrt/imxrt118x/soc.c +++ b/soc/nxp/imxrt/imxrt118x/soc.c @@ -76,6 +76,18 @@ const clock_sys_pll2_config_t sysPll2Config_BOARD_BootClockRUN = { .ssEnable = false, }; +/* Function Name : board_flexspi_clock_safe_config + * Description : FLEXSPI clock source safe configuration weak function. + * Called before clock source configuration. + * Note : Users need override this function to change FLEXSPI clock source to stable + * source when executing code on FLEXSPI memory(XIP). If XIP, the function + * should runs in RAM and move the FLEXSPI clock source to a stable clock + * to avoid instruction/data fetch issue during clock updating. + */ +__attribute__((weak)) void board_flexspi_clock_safe_config(void) +{ +} + /** * @brief Initialize the system clock */ @@ -123,6 +135,12 @@ static ALWAYS_INLINE void clock_init(void) (ANADIG_OSC->OSC_24M_CTRL & ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK)) { } + /* Call function board_flexspi_clock_safe_config() to move FlexSPI clock to a stable + * clock source to avoid instruction/data fetch issue when updating PLL if XIP + * (execute code on FLEXSPI memory). + */ + board_flexspi_clock_safe_config(); + #ifdef CONFIG_INIT_ARM_PLL /* Init Arm Pll. */ CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); @@ -391,6 +409,14 @@ static ALWAYS_INLINE void clock_init(void) #endif /* CONFIG_MCUX_LPTMR_TIMER || CONFIG_COUNTER_MCUX_LPTMR */ +#if !(DT_NODE_HAS_COMPAT(DT_PARENT(DT_CHOSEN(zephyr_flash)), nxp_imx_flexspi_nor)) && \ + defined(CONFIG_MEMC_MCUX_FLEXSPI) && DT_NODE_HAS_STATUS(DT_NODELABEL(flexspi), okay) + /* Configure FLEXSPI1 using SYS_PLL3_PFD0_CLK */ + rootCfg.mux = kCLOCK_FLEXSPI1_ClockRoot_MuxSysPll3Pfd0; + rootCfg.div = 3; + CLOCK_SetRootClock(kCLOCK_Root_Flexspi1, &rootCfg); +#endif + /* Keep core clock ungated during WFI */ CCM->LPCG[1].LPM0 = 0x33333333; CCM->LPCG[1].LPM1 = 0x33333333; @@ -511,8 +537,10 @@ void soc_early_init_hook(void) /* Enable data cache */ #if defined(CONFIG_IMXRT118X_CM33_XCACHE_PS) + XCACHE_EnableCache(XCACHE_PC); XCACHE_EnableCache(XCACHE_PS); #elif defined(CONFIG_SOC_MIMXRT1189_CM7) + sys_cache_instr_enable(); sys_cache_data_enable(); #endif __ISB(); diff --git a/soc/nxp/imxrt/imxrt118x/soc.h b/soc/nxp/imxrt/imxrt118x/soc.h index 272227b3a47..cceb990cc8f 100644 --- a/soc/nxp/imxrt/imxrt118x/soc.h +++ b/soc/nxp/imxrt/imxrt118x/soc.h @@ -20,6 +20,10 @@ extern "C" { #endif +#ifdef CONFIG_MEMC_MCUX_FLEXSPI +uint32_t flexspi_clock_set_freq(uint32_t clock_name, uint32_t rate); +#endif + #ifdef __cplusplus } #endif