From b0bd5a6ece038f7e3722ea810055d8c47118f34a Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Thu, 17 Dec 2020 20:55:28 -0600 Subject: [PATCH] drivers: flash: Introduce i.MX RT FlexSPI driver Introduces a new flash driver for the FlexSPI peripheral on i.MX RT SoCs. The hardware provides a flexible sequence engine (LUT) that supports various types of external devices, including serial NOR flash, serial NAND flash, HyperBus (HyperFlash/HyperRAM), and FPGAs. It supports up to four connected devices in single/dual/quad/octal modes and provides memory-mapped read/write access to these devices through the AHB bus. The driver implementation consists of a shared controller for each FlexSPI peripheral instance, and protocol-specific device drivers for each external device. The controller provides a private interface for multiple devices to access the FlexSPI peripheral registers. FlexSPI devices provide the public flash driver interface to applications or subsystems like storage or flash file systems; they also provide protocol-specific LUT sequences to the controller. Currently the only device type supported is QSPI NOR flash, but other types like HyperFlash will be added later. XIP is not yet supported, as this requires additional work to relocate code to RAM and managing interrupts. Signed-off-by: Maureen Helm --- drivers/flash/CMakeLists.txt | 2 + drivers/flash/Kconfig.mcux | 13 + drivers/flash/flash_mcux_flexspi.c | 147 +++++++ drivers/flash/flash_mcux_flexspi.h | 23 ++ drivers/flash/flash_mcux_flexspi_nor.c | 507 +++++++++++++++++++++++++ west.yml | 2 +- 6 files changed, 693 insertions(+), 1 deletion(-) create mode 100644 drivers/flash/flash_mcux_flexspi.c create mode 100644 drivers/flash/flash_mcux_flexspi.h create mode 100644 drivers/flash/flash_mcux_flexspi_nor.c diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 310672ae752..150bf99702f 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 618b5ea27c4..046bc333599 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 00000000000..b19ccd99d9a --- /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 00000000000..99818dfefcc --- /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 00000000000..7babea172f9 --- /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/west.yml b/west.yml index 0ab21fe4c48..642a70b050f 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