diff --git a/boards/arm/mimxrt1010_evk/mimxrt1010_evk.dts b/boards/arm/mimxrt1010_evk/mimxrt1010_evk.dts index ae44656450e7b..95ad9f373e82a 100644 --- a/boards/arm/mimxrt1010_evk/mimxrt1010_evk.dts +++ b/boards/arm/mimxrt1010_evk/mimxrt1010_evk.dts @@ -46,7 +46,7 @@ arduino_serial: &lpuart1 {}; &flexspi { reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(16)>; at25sf128a: at25sf128a@0 { - compatible = "adesto,at25sf128a", "jedec,spi-nor"; + compatible = "nxp,imx-flexspi-nor"; size = <134217728>; label = "AT25SF128A"; reg = <0>; diff --git a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts index 0f85986351fe9..f8d7373a7d3a7 100644 --- a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts +++ b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts @@ -75,7 +75,7 @@ arduino_serial: &lpuart4 {}; &flexspi { reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(16)>; at25sf128a: at25sf128a@0 { - compatible = "adesto,at25sf128a", "jedec,spi-nor"; + compatible = "nxp,imx-flexspi-nor"; size = <134217728>; label = "AT25SF128A"; reg = <0>; diff --git a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts index 2e2b5e1a76a04..02e1da6a2a916 100644 --- a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts +++ b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts @@ -82,7 +82,7 @@ arduino_serial: &lpuart2 {}; &flexspi { reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; is25wp064: is25wp064@0 { - compatible = "issi,is25wp064", "jedec,spi-nor"; + compatible = "nxp,imx-flexspi-nor"; size = <67108864>; label = "IS25WP064"; reg = <0>; diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts index 1e528b56e8be9..35ef2b9f258bf 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts @@ -92,9 +92,12 @@ arduino_serial: &lpuart3 {}; &flexspi { reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(64)>; - hyperflash0: hyperflash@0 { - compatible = "cypress,s26ks512s"; + s26ks512s0: s26ks512s@0 { + compatible = "nxp,imx-flexspi-hyperflash"; + size = ; + label = "S26KS512S"; reg = <0>; + spi-max-frequency = <166000000>; status = "okay"; }; }; diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.dts b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.dts index 5b84cfc601c11..49f64f886fff7 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.dts +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk_qspi.dts @@ -6,12 +6,12 @@ #include "mimxrt1050_evk.dts" -/delete-node/ &hyperflash0; +/delete-node/ &s26ks512s0; &flexspi { reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; is25wp064: is25wp064@0 { - compatible = "issi,is25wp064", "jedec,spi-nor"; + compatible = "nxp,imx-flexspi-nor"; size = <67108864>; label = "IS25WP064"; reg = <0>; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts index 666200698e731..df7ecac60d19a 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts @@ -94,7 +94,7 @@ arduino_serial: &lpuart3 {}; &flexspi { reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; is25wp064: is25wp064@0 { - compatible = "issi,is25wp064", "jedec,spi-nor"; + compatible = "nxp,imx-flexspi-nor"; size = <67108864>; label = "IS25WP064"; reg = <0>; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.dts b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.dts index 867b34c071024..ef193819db954 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.dts +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_hyperflash.dts @@ -9,9 +9,12 @@ /delete-node/ &is25wp064; &flexspi { reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(64)>; - hyperflash0: hyperflash@0 { - compatible = "cypress,s26ks512s"; + s26ks512s0: s26ks512s@0 { + compatible = "nxp,imx-flexspi-hyperflash"; + size = ; + label = "S26KS512S"; reg = <0>; + spi-max-frequency = <166000000>; status = "okay"; }; }; diff --git a/boards/arm/mimxrt1064_evk/Kconfig.defconfig b/boards/arm/mimxrt1064_evk/Kconfig.defconfig index 52e87780bf2a5..1c49be2bf7d5c 100644 --- a/boards/arm/mimxrt1064_evk/Kconfig.defconfig +++ b/boards/arm/mimxrt1064_evk/Kconfig.defconfig @@ -16,6 +16,9 @@ config DISK_ACCESS_USDHC1 default y depends on DISK_ACCESS_USDHC +config FLASH_MCUX_FLEXSPI_NOR + default y if FLASH + config I2C default y if KSCAN diff --git a/boards/arm/mimxrt1064_evk/doc/index.rst b/boards/arm/mimxrt1064_evk/doc/index.rst index 04fc058d52e3e..aae83997c447e 100644 --- a/boards/arm/mimxrt1064_evk/doc/index.rst +++ b/boards/arm/mimxrt1064_evk/doc/index.rst @@ -219,6 +219,20 @@ The MIMXRT1064 SoC has four pairs of pinmux/gpio controllers. +---------------+-----------------+---------------------------+ | GPIO_SD_B0_05 | USDHC1_DATA3 | SD Card | +---------------+-----------------+---------------------------+ +| GPIO_SD_B1_05 | FLEXSPIA_DQS | QSPI Flash | ++---------------+-----------------+---------------------------+ +| GPIO_SD_B1_06 | FLEXSPIA_SS0_B | QSPI Flash | ++---------------+-----------------+---------------------------+ +| GPIO_SD_B1_07 | FLEXSPIA_SCLK | QSPI Flash | ++---------------+-----------------+---------------------------+ +| GPIO_SD_B1_08 | FLEXSPIA_DATA00 | QSPI Flash | ++---------------+-----------------+---------------------------+ +| GPIO_SD_B1_09 | FLEXSPIA_DATA01 | QSPI Flash | ++---------------+-----------------+---------------------------+ +| GPIO_SD_B1_10 | FLEXSPIA_DATA02 | QSPI Flash | ++---------------+-----------------+---------------------------+ +| GPIO_SD_B1_11 | FLEXSPIA_DATA03 | QSPI Flash | ++---------------+-----------------+---------------------------+ System Clock ============ diff --git a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts index df081245c1436..13e0399c7d594 100644 --- a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts @@ -132,6 +132,34 @@ arduino_i2c: &lpi2c1 {}; }; }; +&flexspi { + status = "okay"; + ahb-prefetch; + ahb-read-addr-opt; + rx-clock-source = <1>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; + is25wp064: is25wp064@0 { + compatible = "nxp,imx-flexspi-nor"; + size = <67108864>; + label = "IS25WP064"; + reg = <0>; + spi-max-frequency = <133000000>; + status = "okay"; + jedec-id = [9d 70 17]; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0x00000000 DT_SIZE_M(8)>; + }; + }; + }; +}; + &lpuart1 { status = "okay"; current-speed = <115200>; diff --git a/boards/arm/mimxrt1064_evk/pinmux.c b/boards/arm/mimxrt1064_evk/pinmux.c index 5e80c3e545418..f64cc1741f377 100644 --- a/boards/arm/mimxrt1064_evk/pinmux.c +++ b/boards/arm/mimxrt1064_evk/pinmux.c @@ -301,6 +301,24 @@ static int mimxrt1064_evk_init(const struct device *dev) imxrt_usdhc_pinmux_cb_register(mimxrt1064_evk_usdhc_pinmux); #endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexspi), okay) && CONFIG_FLASH + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 1U); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0x10F1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0x10F1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0x10F1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0x10F1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0x10F1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0x10F1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0x10F1U); +#endif + return 0; } diff --git a/boards/arm/mm_swiftio/mm_swiftio.dts b/boards/arm/mm_swiftio/mm_swiftio.dts index 8e9a3398c824c..dd882294341df 100644 --- a/boards/arm/mm_swiftio/mm_swiftio.dts +++ b/boards/arm/mm_swiftio/mm_swiftio.dts @@ -55,7 +55,7 @@ &flexspi { reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; is25wp064: is25wp064@0 { - compatible = "issi,is25wp064", "jedec,spi-nor"; + compatible = "nxp,imx-flexspi-nor"; size = <67108864>; label = "IS25WP064"; reg = <0>; diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 310672ae75223..150bf99702f9f 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -17,6 +17,8 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NIOS2_QSPI soc_flash_nios2_qspi.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_GECKO flash_gecko.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_RV32M1 soc_flash_rv32m1.c) zephyr_library_sources_ifdef(CONFIG_FLASH_STM32_QSPI flash_stm32_qspi.c) +zephyr_library_sources_ifdef(CONFIG_FLASH_MCUX_FLEXSPI flash_mcux_flexspi.c) +zephyr_library_sources_ifdef(CONFIG_FLASH_MCUX_FLEXSPI_NOR flash_mcux_flexspi_nor.c) if(CONFIG_SOC_FLASH_STM32) if(CONFIG_SOC_SERIES_STM32H7X) diff --git a/drivers/flash/Kconfig.mcux b/drivers/flash/Kconfig.mcux index 618b5ea27c479..046bc3335993d 100644 --- a/drivers/flash/Kconfig.mcux +++ b/drivers/flash/Kconfig.mcux @@ -23,3 +23,16 @@ config CHECK_BEFORE_READING devices will crash when reading an erased or wrongly programmed area. endif # SOC_FLASH_MCUX + +if HAS_MCUX_FLEXSPI + +config FLASH_MCUX_FLEXSPI_NOR + bool "MCUX FlexSPI NOR driver" + select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_DRIVER_ENABLED + select FLASH_MCUX_FLEXSPI + +config FLASH_MCUX_FLEXSPI + bool + +endif # HAS_MCUX_FLEXSPI diff --git a/drivers/flash/flash_mcux_flexspi.c b/drivers/flash/flash_mcux_flexspi.c new file mode 100644 index 0000000000000..b19ccd99d9aa5 --- /dev/null +++ b/drivers/flash/flash_mcux_flexspi.c @@ -0,0 +1,147 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_imx_flexspi + +#include +#include +#include +#include "flash_mcux_flexspi.h" + +LOG_MODULE_REGISTER(flash_flexspi, CONFIG_FLASH_LOG_LEVEL); + +struct flash_flexspi_config { + FLEXSPI_Type *base; + uint8_t *ahb_base; + bool ahb_bufferable; + bool ahb_cacheable; + bool ahb_prefetch; + bool ahb_read_addr_opt; + bool combination_mode; + flexspi_read_sample_clock_t rx_sample_clock; +}; + +struct flash_flexspi_data { + size_t size[kFLEXSPI_PortCount]; +}; + +int flash_flexspi_update_lut(const struct device *dev, uint32_t index, + const uint32_t *cmd, uint32_t count) +{ + const struct flash_flexspi_config *config = dev->config; + + FLEXSPI_UpdateLUT(config->base, index, cmd, count); + + return 0; +} + +int flash_flexspi_set_flash_config(const struct device *dev, + const flexspi_device_config_t *device_config, + flexspi_port_t port) +{ + const struct flash_flexspi_config *config = dev->config; + struct flash_flexspi_data *data = dev->data; + + if (port >= kFLEXSPI_PortCount) { + LOG_ERR("Invalid port number"); + return -EINVAL; + } + + data->size[port] = device_config->flashSize * KB(1); + + FLEXSPI_SetFlashConfig(config->base, + (flexspi_device_config_t *) device_config, + port); + + return 0; +} + +int flash_flexspi_reset(const struct device *dev) +{ + const struct flash_flexspi_config *config = dev->config; + + FLEXSPI_SoftwareReset(config->base); + + return 0; +} + +int flash_flexspi_transfer(const struct device *dev, + flexspi_transfer_t *transfer) +{ + const struct flash_flexspi_config *config = dev->config; + status_t status = FLEXSPI_TransferBlocking(config->base, transfer); + + if (status != kStatus_Success) { + LOG_ERR("Transfer error: %d", status); + return -EIO; + } + + return 0; +} + +void *flash_flexspi_get_ahb_address(const struct device *dev, + flexspi_port_t port, off_t offset) +{ + const struct flash_flexspi_config *config = dev->config; + struct flash_flexspi_data *data = dev->data; + int i; + + if (port >= kFLEXSPI_PortCount) { + LOG_ERR("Invalid port number"); + return NULL; + } + + for (i = 0; i < port; i++) { + offset += data->size[port]; + } + + return config->ahb_base + offset; +} + +static int flash_flexspi_init(const struct device *dev) +{ + const struct flash_flexspi_config *config = dev->config; + flexspi_config_t flexspi_config; + + FLEXSPI_GetDefaultConfig(&flexspi_config); + + flexspi_config.ahbConfig.enableAHBBufferable = config->ahb_bufferable; + flexspi_config.ahbConfig.enableAHBCachable = config->ahb_cacheable; + flexspi_config.ahbConfig.enableAHBPrefetch = config->ahb_prefetch; + flexspi_config.ahbConfig.enableReadAddressOpt = config->ahb_read_addr_opt; + flexspi_config.enableCombination = config->combination_mode; + flexspi_config.rxSampleClock = config->rx_sample_clock; + + FLEXSPI_Init(config->base, &flexspi_config); + + return 0; +} + +#define FLASH_FLEXSPI(n) \ + static const struct flash_flexspi_config \ + flash_flexspi_config_##n = { \ + .base = (FLEXSPI_Type *) DT_INST_REG_ADDR(n), \ + .ahb_base = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(n, 1), \ + .ahb_bufferable = DT_INST_PROP(n, ahb_bufferable), \ + .ahb_cacheable = DT_INST_PROP(n, ahb_cacheable), \ + .ahb_prefetch = DT_INST_PROP(n, ahb_prefetch), \ + .ahb_read_addr_opt = DT_INST_PROP(n, ahb_read_addr_opt),\ + .combination_mode = DT_INST_PROP(n, combination_mode), \ + .rx_sample_clock = DT_INST_PROP(n, rx_clock_source), \ + }; \ + \ + static struct flash_flexspi_data flash_flexspi_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + flash_flexspi_init, \ + device_pm_control_nop, \ + &flash_flexspi_data_##n, \ + &flash_flexspi_config_##n, \ + POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(FLASH_FLEXSPI) diff --git a/drivers/flash/flash_mcux_flexspi.h b/drivers/flash/flash_mcux_flexspi.h new file mode 100644 index 0000000000000..99818dfefcceb --- /dev/null +++ b/drivers/flash/flash_mcux_flexspi.h @@ -0,0 +1,23 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int flash_flexspi_update_lut(const struct device *dev, uint32_t index, + const uint32_t *cmd, uint32_t count); + +int flash_flexspi_set_flash_config(const struct device *dev, + const flexspi_device_config_t *device_config, + flexspi_port_t port); + +int flash_flexspi_reset(const struct device *dev); + +int flash_flexspi_transfer(const struct device *dev, + flexspi_transfer_t *transfer); + +void *flash_flexspi_get_ahb_address(const struct device *dev, + flexspi_port_t port, off_t offset); diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c new file mode 100644 index 0000000000000..7babea172f9b4 --- /dev/null +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -0,0 +1,507 @@ +/* + * Copyright 2020 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_imx_flexspi_nor + +#include +#include +#include +#include "spi_nor.h" +#include "flash_mcux_flexspi.h" + +#ifdef CONFIG_HAS_MCUX_CACHE +#include +#endif + +#define NOR_WRITE_SIZE 1 +#define NOR_ERASE_VALUE 0xff + +LOG_MODULE_DECLARE(flash_flexspi, CONFIG_FLASH_LOG_LEVEL); + +enum { + /* SPI instructions */ + READ_ID, + READ_STATUS_REG, + WRITE_STATUS_REG, + WRITE_ENABLE, + ERASE_SECTOR, + ERASE_CHIP, + + /* Quad SPI instructions */ + READ_FAST_QUAD_OUTPUT, + PAGE_PROGRAM_QUAD_INPUT, + ENTER_QPI, +}; + +struct flash_flexspi_nor_config { + char *controller_label; + flexspi_port_t port; + flexspi_device_config_t config; + struct flash_pages_layout layout; + struct flash_parameters flash_parameters; +}; + +struct flash_flexspi_nor_data { + const struct device *controller; +}; + +static const uint32_t flash_flexspi_nor_lut[][4] = { + [READ_ID] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDID, + kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), + }, + + [READ_STATUS_REG] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR, + kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), + }, + + [WRITE_STATUS_REG] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_WRSR, + kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04), + }, + + [WRITE_ENABLE] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_WREN, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), + }, + + [ERASE_SECTOR] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_SE, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), + }, + + [ERASE_CHIP] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_CE, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), + }, + + [READ_FAST_QUAD_OUTPUT] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x6B, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x08, + kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04), + }, + + [PAGE_PROGRAM_QUAD_INPUT] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), + }, + + [ENTER_QPI] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), + }, +}; + +static int flash_flexspi_nor_get_vendor_id(const struct device *dev, + uint8_t *vendor_id) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + uint32_t buffer = 0; + int ret; + + flexspi_transfer_t transfer = { + .deviceAddress = 0, + .port = config->port, + .cmdType = kFLEXSPI_Read, + .SeqNumber = 1, + .seqIndex = READ_ID, + .data = &buffer, + .dataSize = 1, + }; + + LOG_DBG("Reading id"); + + ret = flash_flexspi_transfer(data->controller, &transfer); + *vendor_id = buffer; + + return ret; +} + +static int flash_flexspi_nor_read_status(const struct device *dev, + uint32_t *status) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + + flexspi_transfer_t transfer = { + .deviceAddress = 0, + .port = config->port, + .cmdType = kFLEXSPI_Read, + .SeqNumber = 1, + .seqIndex = READ_STATUS_REG, + .data = status, + .dataSize = 1, + }; + + LOG_DBG("Reading status register"); + + return flash_flexspi_transfer(data->controller, &transfer); +} + +static int flash_flexspi_nor_write_status(const struct device *dev, + uint32_t *status) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + + flexspi_transfer_t transfer = { + .deviceAddress = 0, + .port = config->port, + .cmdType = kFLEXSPI_Write, + .SeqNumber = 1, + .seqIndex = WRITE_STATUS_REG, + .data = status, + .dataSize = 1, + }; + + LOG_DBG("Writing status register"); + + return flash_flexspi_transfer(data->controller, &transfer); +} + +static int flash_flexspi_nor_write_enable(const struct device *dev) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + + flexspi_transfer_t transfer = { + .deviceAddress = 0, + .port = config->port, + .cmdType = kFLEXSPI_Command, + .SeqNumber = 1, + .seqIndex = WRITE_ENABLE, + .data = NULL, + .dataSize = 0, + }; + + LOG_DBG("Enabling write"); + + return flash_flexspi_transfer(data->controller, &transfer); +} + +static int flash_flexspi_nor_erase_sector(const struct device *dev, + off_t offset) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + + flexspi_transfer_t transfer = { + .deviceAddress = offset, + .port = config->port, + .cmdType = kFLEXSPI_Command, + .SeqNumber = 1, + .seqIndex = ERASE_SECTOR, + .data = NULL, + .dataSize = 0, + }; + + LOG_DBG("Erasing sector at 0x%08x", offset); + + return flash_flexspi_transfer(data->controller, &transfer); +} + +static int flash_flexspi_nor_erase_chip(const struct device *dev) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + + flexspi_transfer_t transfer = { + .deviceAddress = 0, + .port = config->port, + .cmdType = kFLEXSPI_Command, + .SeqNumber = 1, + .seqIndex = ERASE_CHIP, + .data = NULL, + .dataSize = 0, + }; + + LOG_DBG("Erasing chip"); + + return flash_flexspi_transfer(data->controller, &transfer); +} + +static int flash_flexspi_nor_page_program(const struct device *dev, + off_t offset, const void *buffer, size_t len) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + + flexspi_transfer_t transfer = { + .deviceAddress = offset, + .port = config->port, + .cmdType = kFLEXSPI_Write, + .SeqNumber = 1, + .seqIndex = PAGE_PROGRAM_QUAD_INPUT, + .data = (uint32_t *) buffer, + .dataSize = len, + }; + + LOG_DBG("Page programming %d bytes to 0x%08x", len, offset); + + return flash_flexspi_transfer(data->controller, &transfer); +} + +static int flash_flexspi_nor_wait_bus_busy(const struct device *dev) +{ + uint32_t status = 0; + int ret; + + do { + ret = flash_flexspi_nor_read_status(dev, &status); + LOG_DBG("status: 0x%x", status); + if (ret) { + LOG_ERR("Could not read status"); + return ret; + } + } while (status & BIT(0)); + + return 0; +} + +static int flash_flexspi_nor_enable_quad_mode(const struct device *dev) +{ + struct flash_flexspi_nor_data *data = dev->data; + uint32_t status = 0x40; + + flash_flexspi_nor_write_status(dev, &status); + flash_flexspi_nor_wait_bus_busy(dev); + flash_flexspi_reset(data->controller); + + return 0; +} + +static int flash_flexspi_nor_read(const struct device *dev, off_t offset, + void *buffer, size_t len) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + uint8_t *src = flash_flexspi_get_ahb_address(data->controller, + config->port, + offset); + + memcpy(buffer, src, len); + + return 0; +} + +static int flash_flexspi_nor_write(const struct device *dev, off_t offset, + const void *buffer, size_t len) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + size_t size = len; + uint8_t *src = (uint8_t *) buffer; + int i; + + uint8_t *dst = flash_flexspi_get_ahb_address(data->controller, + config->port, + offset); + + while (len) { + i = MIN(SPI_NOR_PAGE_SIZE, len); + flash_flexspi_nor_write_enable(dev); + flash_flexspi_nor_page_program(dev, offset, src, i); + flash_flexspi_nor_wait_bus_busy(dev); + flash_flexspi_reset(data->controller); + offset += i; + len -= i; + } + +#ifdef CONFIG_HAS_MCUX_CACHE + DCACHE_InvalidateByRange((uint32_t) dst, size); +#endif + + return 0; +} + +static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, + size_t size) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + int num_sectors = size / SPI_NOR_SECTOR_SIZE; + int i; + + uint8_t *dst = flash_flexspi_get_ahb_address(data->controller, + config->port, + offset); + + if (offset % SPI_NOR_SECTOR_SIZE) { + LOG_ERR("Invalid offset"); + return -EINVAL; + } + + if (size % SPI_NOR_SECTOR_SIZE) { + LOG_ERR("Invalid size"); + return -EINVAL; + } + + if ((offset == 0) && (size == config->config.flashSize * KB(1))) { + flash_flexspi_nor_write_enable(dev); + flash_flexspi_nor_erase_chip(dev); + flash_flexspi_nor_wait_bus_busy(dev); + flash_flexspi_reset(data->controller); + } else { + for (i = 0; i < num_sectors; i++) { + flash_flexspi_nor_write_enable(dev); + flash_flexspi_nor_erase_sector(dev, offset); + flash_flexspi_nor_wait_bus_busy(dev); + flash_flexspi_reset(data->controller); + offset += SPI_NOR_SECTOR_SIZE; + } + } + +#ifdef CONFIG_HAS_MCUX_CACHE + DCACHE_InvalidateByRange((uint32_t) dst, size); +#endif + + return 0; +} + +static int flash_flexspi_nor_write_protection(const struct device *dev, + bool enable) +{ + return 0; +} + +static const struct flash_parameters *flash_flexspi_nor_get_parameters( + const struct device *dev) +{ + const struct flash_flexspi_nor_config *config = dev->config; + + return &config->flash_parameters; +} + +#if defined(CONFIG_FLASH_PAGE_LAYOUT) +static void flash_flexspi_nor_pages_layout(const struct device *dev, + const struct flash_pages_layout **layout, size_t *layout_size) +{ + const struct flash_flexspi_nor_config *config = dev->config; + + *layout = &config->layout; + *layout_size = 1; +} +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +static int flash_flexspi_nor_init(const struct device *dev) +{ + const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; + uint8_t vendor_id; + + data->controller = device_get_binding(config->controller_label); + if (data->controller == NULL) { + LOG_ERR("Could not find controller"); + return -EINVAL; + } + + if (flash_flexspi_set_flash_config(data->controller, &config->config, + config->port)) { + LOG_ERR("Could not set flash configuration"); + return -EINVAL; + } + + if (flash_flexspi_update_lut(data->controller, 0, + (const uint32_t *) flash_flexspi_nor_lut, + sizeof(flash_flexspi_nor_lut) / 4)) { + LOG_ERR("Could not update lut"); + return -EINVAL; + } + + flash_flexspi_reset(data->controller); + + if (flash_flexspi_nor_get_vendor_id(dev, &vendor_id)) { + LOG_ERR("Could not read vendor id"); + return -EIO; + } + LOG_DBG("Vendor id: 0x%0x", vendor_id); + + if (flash_flexspi_nor_enable_quad_mode(dev)) { + LOG_ERR("Could not enable quad mode"); + return -EIO; + } + + return 0; +} + +static const struct flash_driver_api flash_flexspi_nor_api = { + .write_protection = flash_flexspi_nor_write_protection, + .erase = flash_flexspi_nor_erase, + .write = flash_flexspi_nor_write, + .read = flash_flexspi_nor_read, + .get_parameters = flash_flexspi_nor_get_parameters, +#if defined(CONFIG_FLASH_PAGE_LAYOUT) + .page_layout = flash_flexspi_nor_pages_layout, +#endif +}; + +#define CONCAT3(x, y, z) x ## y ## z + +#define CS_INTERVAL_UNIT(unit) \ + CONCAT3(kFLEXSPI_CsIntervalUnit, unit, SckCycle) + +#define AHB_WRITE_WAIT_UNIT(unit) \ + CONCAT3(kFLEXSPI_AhbWriteWaitUnit, unit, AhbCycle) + +#define FLASH_FLEXSPI_DEVICE_CONFIG(n) \ + { \ + .flexspiRootClk = MHZ(120), \ + .flashSize = DT_INST_PROP(n, size) / 8 / KB(1), \ + .CSIntervalUnit = \ + CS_INTERVAL_UNIT( \ + DT_INST_PROP(n, cs_interval_unit)), \ + .CSInterval = DT_INST_PROP(n, cs_interval), \ + .CSHoldTime = DT_INST_PROP(n, cs_hold_time), \ + .CSSetupTime = DT_INST_PROP(n, cs_setup_time), \ + .dataValidTime = DT_INST_PROP(n, data_valid_time), \ + .columnspace = DT_INST_PROP(n, column_space), \ + .enableWordAddress = DT_INST_PROP(n, word_addressable), \ + .AWRSeqIndex = 0, \ + .AWRSeqNumber = 0, \ + .ARDSeqIndex = READ_FAST_QUAD_OUTPUT, \ + .ARDSeqNumber = 1, \ + .AHBWriteWaitUnit = \ + AHB_WRITE_WAIT_UNIT( \ + DT_INST_PROP(n, ahb_write_wait_unit)), \ + .AHBWriteWaitInterval = \ + DT_INST_PROP(n, ahb_write_wait_interval), \ + } \ + +#define FLASH_FLEXSPI_NOR(n) \ + static const struct flash_flexspi_nor_config \ + flash_flexspi_nor_config_##n = { \ + .controller_label = DT_INST_BUS_LABEL(n), \ + .port = DT_INST_REG_ADDR(n), \ + .config = FLASH_FLEXSPI_DEVICE_CONFIG(n), \ + .layout = { \ + .pages_count = DT_INST_PROP(n, size) / 8 \ + / SPI_NOR_SECTOR_SIZE, \ + .pages_size = SPI_NOR_SECTOR_SIZE, \ + }, \ + .flash_parameters = { \ + .write_block_size = NOR_WRITE_SIZE, \ + .erase_value = NOR_ERASE_VALUE, \ + }, \ + }; \ + \ + static struct flash_flexspi_nor_data \ + flash_flexspi_nor_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + flash_flexspi_nor_init, \ + device_pm_control_nop, \ + &flash_flexspi_nor_data_##n, \ + &flash_flexspi_nor_config_##n, \ + POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &flash_flexspi_nor_api); + +DT_INST_FOREACH_STATUS_OKAY(FLASH_FLEXSPI_NOR) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index 27276e2b53dfe..fbd1c42ad19b1 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -18,6 +18,12 @@ #define BUF_ARRAY_CNT 16 #define TEST_ARR_SIZE 0x1000 +#ifdef DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL +#define FLASH_DEV_NAME DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL +#else +#define FLASH_DEV_NAME "" +#endif + static uint8_t __aligned(4) test_arr[TEST_ARR_SIZE]; static int parse_helper(const struct shell *shell, size_t *argc, @@ -28,7 +34,7 @@ static int parse_helper(const struct shell *shell, size_t *argc, *addr = strtoul((*argv)[1], &endptr, 16); *flash_dev = device_get_binding((*endptr != '\0') ? (*argv)[1] : - DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL); + FLASH_DEV_NAME); if (!*flash_dev) { shell_error(shell, "Flash driver was not found!"); return -ENODEV; diff --git a/dts/arm/nxp/nxp_rt.dtsi b/dts/arm/nxp/nxp_rt.dtsi index 05bf7304e3ae7..ff609c56cf8a9 100644 --- a/dts/arm/nxp/nxp_rt.dtsi +++ b/dts/arm/nxp/nxp_rt.dtsi @@ -72,6 +72,9 @@ label = "FLEXSPI"; #address-cells = <1>; #size-cells = <0>; + ahb-bufferable; + ahb-cacheable; + status = "disabled"; }; flexspi2: spi@402a4000 { @@ -81,6 +84,9 @@ label = "FLEXSPI1"; #address-cells = <1>; #size-cells = <0>; + ahb-bufferable; + ahb-cacheable; + status = "disabled"; }; semc: semc0@402f0000 { diff --git a/dts/arm/nxp/nxp_rt1064.dtsi b/dts/arm/nxp/nxp_rt1064.dtsi index 3ab7a9065991a..8acb26befb4c9 100644 --- a/dts/arm/nxp/nxp_rt1064.dtsi +++ b/dts/arm/nxp/nxp_rt1064.dtsi @@ -10,7 +10,7 @@ reg = <0x402a4000 0x4000>, <0x70000000 DT_SIZE_M(4)>; /* WINBOND */ w25q32jvwj0: w25q32jvwj@0 { - compatible = "winbond,w25q32jvwj", "jedec,spi-nor"; + compatible = "nxp,imx-flexspi-nor"; size = <33554432>; label = "W25Q32JVWJ0"; reg = <0>; diff --git a/dts/bindings/mtd/nxp,imx-flexspi-device.yaml b/dts/bindings/mtd/nxp,imx-flexspi-device.yaml new file mode 100644 index 0000000000000..f084e447de415 --- /dev/null +++ b/dts/bindings/mtd/nxp,imx-flexspi-device.yaml @@ -0,0 +1,101 @@ +# Copyright 2020 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP FlexSPI device + +compatible: "nxp,imx-flexspi-device" + +include: [spi-device.yaml, "jedec,jesd216.yaml"] + +properties: + cs-interval-unit: + type: int + required: false + default: 1 + enum: + - 1 + - 256 + description: | + Chip select interval units, in serial clock cycles. See the + CSINTERVALUNIT field in registers FLASHA1CR0 through FLASHB2CR0. The + default corresponds to the reset value of the register field. + + cs-interval: + type: int + required: false + default: 0 + description: | + Minimum interval between chip select deassertion and assertion. See the + CSINTERVAL field in registers FLASHA1CR0 through FLASHB2CR0. The + default corresponds to the reset value of the register field. + + cs-setup-time: + type: int + required: false + default: 3 + description: | + Chip select setup time, in serial clock cycles. See the TCSS field in + registers FLASHA1CR0 through FLASHB2CR0. The default corresponds to the + reset value of the register field. + + cs-hold-time: + type: int + required: false + default: 3 + description: | + Chip select hold time, in serial clock cycles. See the TCSH field in + registers FLASHA1CR0 through FLASHB2CR0. The default corresponds to the + reset value of the register field. + + data-valid-time: + type: int + required: false + default: 0 + description: | + Data valid time, in nanoseconds. See the registers DLLACR through + DLLBCR. + + column-space: + type: int + required: false + default: 0 + description: | + Column address bit width. Set to zero if the flash does not support + column address. See the CAS field in registers FLASHA1CR0 through + FLASHB2CR0. The default corresponds to the reset value of the register + field. + + word-addressable: + type: boolean + required: false + description: | + Don't transmit the least significant address bit when the flash is word + addressable. See the WA field in registers FLASHA1CR0 through + FLASHB2CR0. + + ahb-write-wait-unit: + type: int + required: false + default: 2 + enum: + - 2 + - 8 + - 32 + - 128 + - 512 + - 2048 + - 8192 + - 32768 + description: | + AHB write wait interval units, in AHB clock cycles. See the AWRWAITUNIT + field in registers FLASHA1CR2 through FLASHB2CR2. The default + corresponds to the reset value of the register field. + + ahb-write-wait-interval: + type: int + required: false + default: 0 + description: | + Time to wait between AHB triggered command sequences. See the AWRWAIT + field in registers FLASHA1CR2 through FLASHB2CR2. The default + corresponds to the reset value of the register field. diff --git a/dts/bindings/mtd/nxp,imx-flexspi-hyperflash.yaml b/dts/bindings/mtd/nxp,imx-flexspi-hyperflash.yaml new file mode 100644 index 0000000000000..e60450a6e88fb --- /dev/null +++ b/dts/bindings/mtd/nxp,imx-flexspi-hyperflash.yaml @@ -0,0 +1,8 @@ +# Copyright 2020 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP FlexSPI HyperFlash + +compatible: "nxp,imx-flexspi-hyperflash" + +include: nxp,imx-flexspi-device.yaml diff --git a/dts/bindings/mtd/nxp,imx-flexspi-nor.yaml b/dts/bindings/mtd/nxp,imx-flexspi-nor.yaml new file mode 100644 index 0000000000000..6991c892e492e --- /dev/null +++ b/dts/bindings/mtd/nxp,imx-flexspi-nor.yaml @@ -0,0 +1,8 @@ +# Copyright 2020 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP FlexSPI NOR + +compatible: "nxp,imx-flexspi-nor" + +include: nxp,imx-flexspi-device.yaml diff --git a/dts/bindings/spi/nxp,imx-flexspi.yaml b/dts/bindings/spi/nxp,imx-flexspi.yaml index 07b269c4586b2..995ebed636f87 100644 --- a/dts/bindings/spi/nxp,imx-flexspi.yaml +++ b/dts/bindings/spi/nxp,imx-flexspi.yaml @@ -13,3 +13,55 @@ properties: interrupts: required: true + + ahb-bufferable: + type: boolean + required: false + description: | + Enable AHB bufferable write access by setting register field + AHBCR[BUFFERABLEEN]. + + ahb-cacheable: + type: boolean + required: false + description: | + Enable AHB cacheable read access by setting register field + AHBCR[CACHEABLEEN]. + + ahb-prefetch: + type: boolean + required: false + description: | + Enable AHB read prefetch by setting register field AHBCR[PREFETCHEN]. + + ahb-read-addr-opt: + type: boolean + required: false + description: | + Remove burst start address alignment limitation by setting register + field AHBCR[READADDROPT]. + + combination-mode: + type: boolean + required: false + description: | + Combine port A and port B data pins to support octal mode access by + setting register field MCR0[COMBINATIONEN]. + + rx-clock-source: + type: int + required: false + default: 0 + enum: + - 0 # Loopback internally + - 1 # Loopback from DQS pad + - 2 # Loopback from SCK pad + - 3 # External input from DQS pad + description: | + Source clock for flash read. See the RXCLKSRC field in register MCR0. + The default corresponds to the reset value of the register field. + +child-binding: + description: NXP FlexSPI port + + include: nxp,imx-flexspi-device.yaml diff --git a/modules/Kconfig.mcux b/modules/Kconfig.mcux index 40c181c21acce..66536cb157249 100644 --- a/modules/Kconfig.mcux +++ b/modules/Kconfig.mcux @@ -67,6 +67,11 @@ config HAS_MCUX_FLEXCOMM help Set if the flexcomm (FLEXCOMM) module is present in the SoC. +config HAS_MCUX_FLEXSPI + bool + help + Set if the flexible SPI (FlexSPI) module is present in the SoC. + config HAS_MCUX_FTFX bool help diff --git a/samples/drivers/flash_shell/sample.yaml b/samples/drivers/flash_shell/sample.yaml index 783de50145bf5..11e0f6c611282 100644 --- a/samples/drivers/flash_shell/sample.yaml +++ b/samples/drivers/flash_shell/sample.yaml @@ -5,6 +5,7 @@ sample: tests: sample.drivers.flash.shell: tags: flash shell - filter: CONFIG_FLASH_HAS_DRIVER_ENABLED and dt_chosen_enabled("zephyr,flash-controller") + filter: CONFIG_FLASH_HAS_DRIVER_ENABLED + platform_exclude: nucleo_h745zi_q_m4 stm32h747i_disco_m4 harness: keyboard min_ram: 12 diff --git a/samples/subsys/fs/littlefs/sample.yaml b/samples/subsys/fs/littlefs/sample.yaml index eec5ff72eb8df..b6d7883f67618 100644 --- a/samples/subsys/fs/littlefs/sample.yaml +++ b/samples/subsys/fs/littlefs/sample.yaml @@ -4,4 +4,5 @@ tests: sample.filesystem.littlefs: build_only: true platform_allow: nrf52840dk_nrf52840 particle_xenon disco_l475_iot1 + mimxrt1064_evk tags: filesystem diff --git a/soc/arm/nxp_imx/rt/Kconfig.soc b/soc/arm/nxp_imx/rt/Kconfig.soc index f279a364c8a5b..78e9b3b9be5ec 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.soc +++ b/soc/arm/nxp_imx/rt/Kconfig.soc @@ -12,6 +12,7 @@ config SOC_MIMXRT1011 select HAS_MCUX select HAS_MCUX_CACHE select HAS_MCUX_CCM + select HAS_MCUX_FLEXSPI select HAS_MCUX_IGPIO select HAS_MCUX_LPI2C select HAS_MCUX_LPSPI @@ -32,6 +33,7 @@ config SOC_MIMXRT1015 select HAS_MCUX select HAS_MCUX_CACHE select HAS_MCUX_CCM + select HAS_MCUX_FLEXSPI select HAS_MCUX_IGPIO select HAS_MCUX_LPI2C select HAS_MCUX_LPSPI @@ -54,6 +56,7 @@ config SOC_MIMXRT1021 select HAS_MCUX_CACHE select HAS_MCUX_CCM select HAS_MCUX_ENET + select HAS_MCUX_FLEXSPI select HAS_MCUX_IGPIO select HAS_MCUX_LPI2C select HAS_MCUX_LPSPI @@ -78,6 +81,7 @@ config SOC_MIMXRT1051 select HAS_MCUX_CACHE select HAS_MCUX_CCM select HAS_MCUX_ENET + select HAS_MCUX_FLEXSPI select HAS_MCUX_IGPIO select HAS_MCUX_LPI2C select HAS_MCUX_LPSPI @@ -104,6 +108,7 @@ config SOC_MIMXRT1052 select HAS_MCUX_CCM select HAS_MCUX_ELCDIF select HAS_MCUX_ENET + select HAS_MCUX_FLEXSPI select HAS_MCUX_IGPIO select HAS_MCUX_LPI2C select HAS_MCUX_LPSPI @@ -132,6 +137,7 @@ config SOC_MIMXRT1061 select HAS_MCUX_CACHE select HAS_MCUX_CCM select HAS_MCUX_ENET + select HAS_MCUX_FLEXSPI select HAS_MCUX_IGPIO select HAS_MCUX_LPI2C select HAS_MCUX_LPUART @@ -157,6 +163,7 @@ config SOC_MIMXRT1062 select HAS_MCUX_CCM select HAS_MCUX_ELCDIF select HAS_MCUX_ENET + select HAS_MCUX_FLEXSPI select HAS_MCUX_PWM select HAS_MCUX_IGPIO select HAS_MCUX_LPI2C @@ -185,6 +192,7 @@ config SOC_MIMXRT1064 select HAS_MCUX_CCM select HAS_MCUX_ELCDIF select HAS_MCUX_ENET + select HAS_MCUX_FLEXSPI select HAS_MCUX_PWM select HAS_MCUX_IGPIO select HAS_MCUX_LPI2C diff --git a/soc/arm/nxp_imx/rt/soc.c b/soc/arm/nxp_imx/rt/soc.c index f185983ee2e13..9cf55b7dcec57 100644 --- a/soc/arm/nxp_imx/rt/soc.c +++ b/soc/arm/nxp_imx/rt/soc.c @@ -213,6 +213,13 @@ static ALWAYS_INLINE void clock_init(void) CLOCK_SetMux(kCLOCK_CanMux, 2); /* Set Can clock source. */ #endif +#if defined(CONFIG_FLASH_MCUX_FLEXSPI) && DT_NODE_HAS_STATUS(DT_NODELABEL(flexspi), okay) + CLOCK_DisableClock(kCLOCK_FlexSpi); + CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24); + CLOCK_SetMux(kCLOCK_FlexspiMux, 3); + CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2); +#endif + /* Keep the system clock running so SYSTICK can wake up the system from * wfi. */ diff --git a/soc/arm/nxp_imx/rt6xx/Kconfig.soc b/soc/arm/nxp_imx/rt6xx/Kconfig.soc index dd15fcd527c40..6dd2bd678e032 100644 --- a/soc/arm/nxp_imx/rt6xx/Kconfig.soc +++ b/soc/arm/nxp_imx/rt6xx/Kconfig.soc @@ -18,6 +18,7 @@ config SOC_MIMXRT685S_CM33 select HAS_MCUX select HAS_MCUX_SYSCON select HAS_MCUX_FLEXCOMM + select HAS_MCUX_FLEXSPI select HAS_MCUX_CACHE select HAS_MCUX_LPC_DMA select INIT_SYS_PLL diff --git a/west.yml b/west.yml index 0ab21fe4c4831..642a70b050f69 100644 --- a/west.yml +++ b/west.yml @@ -103,7 +103,7 @@ manifest: revision: 41132e9220f8bc1223084975350c5e5f3b492afe path: tools/net-tools - name: hal_nxp - revision: 74ec105b931773854384ecabe95d7552c82e59e4 + revision: b916bca1d5976b0157be80b326e3bb46ef605286 path: modules/hal/nxp - name: open-amp revision: de1b85a13032a2de1d8b6695ae5f800b613e739d