soc: nxp: imxrt: imxrt118x: add flexspi support

add flexspi.c file to get flexspi clock rate.

Enable flexspi1 clock if don't boot from flash.

Use custom fixed mpu_regions.c file to config MPU for CM7

Signed-off-by: Lucien Zhao <lucien.zhao@nxp.com>
diff --git a/soc/nxp/imxrt/CMakeLists.txt b/soc/nxp/imxrt/CMakeLists.txt
index ac5302a..5984d08 100644
--- a/soc/nxp/imxrt/CMakeLists.txt
+++ b/soc/nxp/imxrt/CMakeLists.txt
@@ -39,6 +39,9 @@
 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 da554b9..faabf48 100644
--- a/soc/nxp/imxrt/imxrt118x/CMakeLists.txt
+++ b/soc/nxp/imxrt/imxrt118x/CMakeLists.txt
@@ -13,4 +13,11 @@
 
 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 c8bcbee..b2aa590 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 0000000..b8b49a8
--- /dev/null
+++ b/soc/nxp/imxrt/imxrt118x/flexspi.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <fsl_clock.h>
+#include <fsl_flexspi.h>
+#include <soc.h>
+#include <errno.h>
+#include <zephyr/irq.h>
+#include <zephyr/dt-bindings/clock/imx_ccm_rev2.h>
+
+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 f170b94..fa4d307 100644
--- a/soc/nxp/imxrt/imxrt118x/soc.c
+++ b/soc/nxp/imxrt/imxrt118x/soc.c
@@ -76,6 +76,18 @@
 	.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 @@
 			(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 @@
 
 #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 @@
 
 	/* 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 272227b..cceb990 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