diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig index 45ba1b7f6e2..c40df7b59a4 100644 --- a/arch/arm/src/imxrt/Kconfig +++ b/arch/arm/src/imxrt/Kconfig @@ -1142,12 +1142,28 @@ menuconfig IMXRT_FLEXSPI1 default n select IMXRT_FLEXSPI +menuconfig IMXRT_FLEXSPI1_XIP + bool "FLEXSPI1 is used for XIP" + default n + depends on IMXRT_FLEXSPI1 + ---help--- + FlexSPI1 is used as XIP thus already + initialized by the bootloader + menuconfig IMXRT_FLEXSPI2 bool "FLEXSPI2" default n select IMXRT_FLEXSPI depends on IMXRT_HAVE_FLEXSPI2 +menuconfig IMXRT_FLEXSPI2_XIP + bool "FLEXSPI2 is used for XIP" + default n + depends on IMXRT_FLEXSPI2 + ---help--- + FlexSPI2 is used as XIP thus already + initialized by the bootloader + endmenu # FLEXSPI Peripherals menu "ADC Peripherals" diff --git a/arch/arm/src/imxrt/imxrt_flexspi.c b/arch/arm/src/imxrt/imxrt_flexspi.c index bd1a7375e81..5fded6a92bf 100644 --- a/arch/arm/src/imxrt/imxrt_flexspi.c +++ b/arch/arm/src/imxrt/imxrt_flexspi.c @@ -81,6 +81,7 @@ static int imxrt_flexspi_lock(struct flexspi_dev_s *dev, bool lock); static int imxrt_flexspi_transfer_blocking(struct flexspi_dev_s *dev, struct flexspi_transfer_s *xfer); static void imxrt_flexspi_software_reset(struct flexspi_dev_s *dev); +static void imxrt_flexspi_configure_prefetch(struct flexspi_dev_s *dev, bool enable); static void imxrt_flexspi_update_lut(struct flexspi_dev_s *dev, uint32_t index, const uint32_t *cmd, @@ -100,6 +101,7 @@ static const struct flexspi_ops_s g_flexspi0ops = .lock = imxrt_flexspi_lock, .transfer_blocking = imxrt_flexspi_transfer_blocking, .software_reset = imxrt_flexspi_software_reset, + .configure_prefetch = imxrt_flexspi_configure_prefetch, .update_lut = imxrt_flexspi_update_lut, .set_device_config = imxrt_flexspi_set_device_config, }; @@ -115,12 +117,14 @@ static struct imxrt_flexspidev_s g_flexspi0dev = .ops = &g_flexspi0ops, }, .base = (struct flexspi_type_s *) IMXRT_FLEXSPIC_BASE, +#ifdef CONFIG_IMXRT_FLEXSPI1_XIP + .initialized = true, +#endif }; #endif #ifdef CONFIG_IMXRT_FLEXSPI2 - static struct imxrt_flexspidev_s g_flexspi1dev = { .flexspi = @@ -128,6 +132,9 @@ static struct imxrt_flexspidev_s g_flexspi1dev = .ops = &g_flexspi0ops, }, .base = (struct flexspi_type_s *) IMXRT_FLEXSPI2C_BASE, +#ifdef CONFIG_IMXRT_FLEXSPI2_XIP + .initialized = true, +#endif }; #endif @@ -327,6 +334,29 @@ static inline void imxrt_flexspi_software_reset_private( } } +/* Configure FLEXSPI preftech. + * + * This function enables/disabled the prefetcher + * Which is needed to do RWW see NXP AN12564 + * + * @param base FLEXSPI peripheral base address. + */ + +static inline void imxrt_flexspi_configure_prefetch_private( + struct flexspi_type_s *base, bool enable) +{ + uint32_t config_value = base->AHBCR; + + if(enable) { + config_value |= FLEXSPI_AHBCR_PREFETCHEN(1); + } else { + config_value &= ~FLEXSPI_AHBCR_PREFETCHEN(1); + } + + base->AHBCR = config_value; +} + + /* Returns whether the bus is idle. * * @param base FLEXSPI peripheral base address. @@ -1170,6 +1200,28 @@ static void imxrt_flexspi_software_reset(struct flexspi_dev_s *dev) imxrt_flexspi_software_reset_private(priv->base); } +/**************************************************************************** + * Name: imxrt_flexspi_software_reset + * + * Description: + * Performs a software reset of FlexSPI + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void imxrt_flexspi_configure_prefetch(struct flexspi_dev_s *dev, bool enable) +{ + struct imxrt_flexspidev_s *priv = (struct imxrt_flexspidev_s *)dev; + + imxrt_flexspi_configure_prefetch_private(priv->base, enable); +} + + /**************************************************************************** * Name: imxrt_flexspi_update_lut * diff --git a/arch/arm/src/imxrt/imxrt_flexspi.h b/arch/arm/src/imxrt/imxrt_flexspi.h index e2cfbc803bd..e54dd8a9f45 100644 --- a/arch/arm/src/imxrt/imxrt_flexspi.h +++ b/arch/arm/src/imxrt/imxrt_flexspi.h @@ -125,6 +125,23 @@ #define FLEXSPI_TRANSFER(d,x) (d)->ops->transfer_blocking(d,x) +/**************************************************************************** + * Name: FLEXSPI_CONFIGURE_PREFTECH + * + * Description: + * Enable / disable prefetch + * + * Input Parameters: + * dev - Device-specific state data + * enable - Enable prefetch + * + * Returned Value: + * none + * + ****************************************************************************/ + +#define FLEXSPI_CONFIGURE_PREFETCH(d,e) (d)->ops->configure_prefetch(d,e) + /**************************************************************************** * Name: FLEXSPI_SOFTWARE_RESET * @@ -506,6 +523,7 @@ struct flexspi_ops_s int (*transfer_blocking)(struct flexspi_dev_s *dev, struct flexspi_transfer_s *xfer); void (*software_reset)(struct flexspi_dev_s *dev); + void (*configure_prefetch)(struct flexspi_dev_s *dev, bool enable); void (*update_lut)(struct flexspi_dev_s *dev, uint32_t index, const uint32_t *cmd, uint32_t count); diff --git a/arch/arm/src/imxrt/imxrt_periphclks.h b/arch/arm/src/imxrt/imxrt_periphclks.h index a79c90526b8..566387b4423 100644 --- a/arch/arm/src/imxrt/imxrt_periphclks.h +++ b/arch/arm/src/imxrt/imxrt_periphclks.h @@ -257,6 +257,7 @@ #define imxrt_clockrun_flexram() imxrt_periphclk_configure(CCM_CCGR_FLEXRAM, CCM_CG_RUN) #ifndef CONFIG_ARCH_FAMILY_IMXRT117x # define imxrt_clockrun_flexspi() imxrt_periphclk_configure(CCM_CCGR_FLEXSPI, CCM_CG_RUN) +# define imxrt_clockrun_flexspi2() imxrt_periphclk_configure(CCM_CCGR_FLEXSPI2, CCM_CG_RUN) #else # define imxrt_clockrun_flexspi() imxrt_periphclk_configure(CCM_CCGR_FLEXSPI1, CCM_CG_RUN) # define imxrt_clockrun_flexspi2() imxrt_periphclk_configure(CCM_CCGR_FLEXSPI2, CCM_CG_RUN)