diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.c b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.c deleted file mode 100644 index 07df334ad9e..00000000000 --- a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.c +++ /dev/null @@ -1,701 +0,0 @@ -/**************************************************************************** - * boards/arm/imxrt/imxrt1064-evk/src/imxrt_flexspi_nor.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "imxrt_flexspi.h" -#include "imxrt1064-evk.h" -#include "hardware/imxrt_pinmux.h" - -#ifdef CONFIG_IMXRT_FLEXSPI - -#define NOR_PAGE_SIZE 0x0100U -#define NOR_SECTOR_SIZE 0x1000U - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -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, -}; - -static const uint32_t g_flexspi_nor_lut[][4] = -{ - [READ_ID] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x9f, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_1PAD, 0x04), - }, - - [READ_STATUS_REG] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x05, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_1PAD, 0x04), - }, - - [WRITE_STATUS_REG] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x01, - FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_1PAD, 0x04), - }, - - [WRITE_ENABLE] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x06, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - - [ERASE_SECTOR] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x20, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - }, - - [ERASE_CHIP] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0xc7, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - - [READ_FAST_QUAD_OUTPUT] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x6b, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_DUMMY_SDR, FLEXSPI_4PAD, 0x08, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_4PAD, 0x04), - }, - - [PAGE_PROGRAM_QUAD_INPUT] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x32, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_4PAD, 0x04, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - - [ENTER_QPI] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x35, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, -}; - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/* FlexSPI NOR device private data */ - -struct imxrt_flexspi_nor_dev_s -{ - struct mtd_dev_s mtd; - struct flexspi_dev_s *flexspi; /* Saved FlexSPI interface instance */ - uint8_t *ahb_base; - enum flexspi_port_e port; - struct flexspi_device_config_s *config; -}; - -/**************************************************************************** - * Private Functions Prototypes - ****************************************************************************/ - -/* MTD driver methods */ - -static int imxrt_flexspi_nor_erase(FAR struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks); -static ssize_t imxrt_flexspi_nor_read(FAR struct mtd_dev_s *dev, - off_t offset, - size_t nbytes, - FAR uint8_t *buffer); -static ssize_t imxrt_flexspi_nor_bread(FAR struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks, - FAR uint8_t *buffer); -static ssize_t imxrt_flexspi_nor_bwrite(FAR struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks, - FAR const uint8_t *buffer); -static int imxrt_flexspi_nor_ioctl(FAR struct mtd_dev_s *dev, - int cmd, - unsigned long arg); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static struct flexspi_device_config_s g_flexspi_device_config = -{ - .flexspi_root_clk = 120000000, - .flash_size = 8192, - .cs_interval_unit = FLEXSPI_CS_INTERVAL_UNIT1_SCK_CYCLE, - .cs_interval = 0, - .cs_hold_time = 3, - .cs_setup_time = 3, - .data_valid_time = 0, - .columnspace = 0, - .enable_word_address = 0, - .awr_seq_index = 0, - .awr_seq_number = 0, - .ard_seq_index = READ_FAST_QUAD_OUTPUT, - .ard_seq_number = 1, - .ahb_write_wait_unit = FLEXSPI_AHB_WRITE_WAIT_UNIT2_AHB_CYCLE, - .ahb_write_wait_interval = 0 -}; - -static struct imxrt_flexspi_nor_dev_s g_flexspi_nor = -{ - .mtd = - { - .erase = imxrt_flexspi_nor_erase, - .bread = imxrt_flexspi_nor_bread, - .bwrite = imxrt_flexspi_nor_bwrite, - .read = imxrt_flexspi_nor_read, - .ioctl = imxrt_flexspi_nor_ioctl, -#ifdef CONFIG_MTD_BYTE_WRITE - .write = NULL, -#endif - .name = "imxrt_flexspi_nor" - }, - .flexspi = (void *)0, - .ahb_base = (uint8_t *) 0x60000000, - .port = FLEXSPI_PORT_A1, - .config = &g_flexspi_device_config -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static int imxrt_flexspi_nor_get_vendor_id( - const struct imxrt_flexspi_nor_dev_s *dev, - uint8_t *vendor_id) -{ - uint32_t buffer = 0; - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_READ, - .seq_number = 1, - .seq_index = READ_ID, - .data = &buffer, - .data_size = 1, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - *vendor_id = buffer; - - return 0; -} - -static int imxrt_flexspi_nor_read_status( - const struct imxrt_flexspi_nor_dev_s *dev, - uint32_t *status) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_READ, - .seq_number = 1, - .seq_index = READ_STATUS_REG, - .data = status, - .data_size = 1, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_nor_write_status( - const struct imxrt_flexspi_nor_dev_s *dev, - uint32_t *status) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_WRITE, - .seq_number = 1, - .seq_index = WRITE_STATUS_REG, - .data = status, - .data_size = 1, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_nor_write_enable( - const struct imxrt_flexspi_nor_dev_s *dev) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_COMMAND, - .seq_number = 1, - .seq_index = WRITE_ENABLE, - .data = NULL, - .data_size = 0, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_nor_erase_sector( - const struct imxrt_flexspi_nor_dev_s *dev, - off_t offset) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = offset, - .port = dev->port, - .cmd_type = FLEXSPI_COMMAND, - .seq_number = 1, - .seq_index = ERASE_SECTOR, - .data = NULL, - .data_size = 0, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_nor_erase_chip( - const struct imxrt_flexspi_nor_dev_s *dev) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_COMMAND, - .seq_number = 1, - .seq_index = ERASE_CHIP, - .data = NULL, - .data_size = 0, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_nor_page_program( - const struct imxrt_flexspi_nor_dev_s *dev, - off_t offset, - const void *buffer, - size_t len) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = offset, - .port = dev->port, - .cmd_type = FLEXSPI_WRITE, - .seq_number = 1, - .seq_index = PAGE_PROGRAM_QUAD_INPUT, - .data = (uint32_t *) buffer, - .data_size = len, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int imxrt_flexspi_nor_wait_bus_busy( - const struct imxrt_flexspi_nor_dev_s *dev) -{ - uint32_t status = 0; - int ret; - - do - { - ret = imxrt_flexspi_nor_read_status(dev, &status); - if (ret) - { - return ret; - } - } - while (status & 1); - - return 0; -} - -static int imxrt_flexspi_nor_enable_quad_mode( - const struct imxrt_flexspi_nor_dev_s *dev) -{ - uint32_t status = 0x40; - - imxrt_flexspi_nor_write_status(dev, &status); - imxrt_flexspi_nor_wait_bus_busy(dev); - FLEXSPI_SOFTWARE_RESET(dev->flexspi); - - return 0; -} - -static ssize_t imxrt_flexspi_nor_read(FAR struct mtd_dev_s *dev, - off_t offset, - size_t nbytes, - FAR uint8_t *buffer) -{ - FAR struct imxrt_flexspi_nor_dev_s *priv = - (FAR struct imxrt_flexspi_nor_dev_s *)dev; - uint8_t *src; - - finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); - - if (priv->port >= FLEXSPI_PORT_COUNT) - { - return -EIO; - } - - src = priv->ahb_base + offset; - - memcpy(buffer, src, nbytes); - - finfo("return nbytes: %d\n", (int)nbytes); - return (ssize_t)nbytes; -} - -static ssize_t imxrt_flexspi_nor_bread(FAR struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks, - FAR uint8_t *buffer) -{ - ssize_t nbytes; - - finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - - /* On this device, we can handle the block read just like the byte-oriented - * read - */ - - nbytes = imxrt_flexspi_nor_read(dev, startblock * NOR_PAGE_SIZE, - nblocks * NOR_PAGE_SIZE, buffer); - if (nbytes > 0) - { - nbytes /= NOR_PAGE_SIZE; - } - - return nbytes; -} - -static ssize_t imxrt_flexspi_nor_bwrite(FAR struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks, - FAR const uint8_t *buffer) -{ - FAR struct imxrt_flexspi_nor_dev_s *priv = - (FAR struct imxrt_flexspi_nor_dev_s *)dev; - size_t len = nblocks * NOR_PAGE_SIZE; - off_t offset = startblock * NOR_PAGE_SIZE; - uint8_t *src = (uint8_t *) buffer; - uint8_t *dst = priv->ahb_base + startblock * NOR_PAGE_SIZE; - int i; - - finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - - while (len) - { - i = MIN(NOR_PAGE_SIZE, len); - imxrt_flexspi_nor_write_enable(priv); - imxrt_flexspi_nor_page_program(priv, offset, src, i); - imxrt_flexspi_nor_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); - offset += i; - len -= i; - } - -#ifdef CONFIG_ARMV7M_DCACHE - up_invalidate_dcache((uintptr_t)dst, - (uintptr_t)dst + nblocks * NOR_PAGE_SIZE); -#endif - - return nblocks; -} - -static int imxrt_flexspi_nor_erase(FAR struct mtd_dev_s *dev, - off_t startblock, - size_t nblocks) -{ - FAR struct imxrt_flexspi_nor_dev_s *priv = - (FAR struct imxrt_flexspi_nor_dev_s *)dev; - size_t blocksleft = nblocks; - uint8_t *dst = priv->ahb_base + startblock * NOR_SECTOR_SIZE; - - finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - - while (blocksleft-- > 0) - { - /* Erase each sector */ - - imxrt_flexspi_nor_write_enable(priv); - imxrt_flexspi_nor_erase_sector(priv, startblock * NOR_SECTOR_SIZE); - imxrt_flexspi_nor_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); - startblock++; - } - -#ifdef CONFIG_ARMV7M_DCACHE - up_invalidate_dcache((uintptr_t)dst, - (uintptr_t)dst + nblocks * NOR_SECTOR_SIZE); -#endif - - return (int)nblocks; -} - -static int imxrt_flexspi_nor_ioctl(FAR struct mtd_dev_s *dev, - int cmd, - unsigned long arg) -{ - FAR struct imxrt_flexspi_nor_dev_s *priv = - (FAR struct imxrt_flexspi_nor_dev_s *)dev; - int ret = -EINVAL; /* Assume good command with bad parameters */ - - finfo("cmd: %d \n", cmd); - - switch (cmd) - { - case MTDIOC_GEOMETRY: - { - FAR struct mtd_geometry_s *geo = - (FAR struct mtd_geometry_s *)((uintptr_t)arg); - - if (geo) - { - /* Populate the geometry structure with information need to - * know the capacity and how to access the device. - * - * NOTE: - * that the device is treated as though it where just an array - * of fixed size blocks. That is most likely not true, but the - * client will expect the device logic to do whatever is - * necessary to make it appear so. - */ - - geo->blocksize = (NOR_PAGE_SIZE); - geo->erasesize = (NOR_SECTOR_SIZE); - geo->neraseblocks = 2048; /* 8MB only */ - - ret = OK; - - finfo("blocksize: %lu erasesize: %lu neraseblocks: %lu\n", - geo->blocksize, geo->erasesize, geo->neraseblocks); - } - } - break; - - case MTDIOC_BULKERASE: - { - /* Erase the entire device */ - - imxrt_flexspi_nor_write_enable(priv); - imxrt_flexspi_nor_erase_chip(priv); - imxrt_flexspi_nor_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); - } - break; - - case MTDIOC_PROTECT: - - /* TODO */ - - break; - - case MTDIOC_UNPROTECT: - - /* TODO */ - - break; - - default: - ret = -ENOTTY; /* Bad/unsupported command */ - break; - } - - finfo("return %d\n", ret); - return ret; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: imxrt_flexspi_nor_initialize - * - * Description: - * This function is called by board-bringup logic to configure the - * flash device. - * - * Returned Value: - * Zero is returned on success. Otherwise, a negated errno value is - * returned to indicate the nature of the failure. - * - ****************************************************************************/ - -int imxrt_flexspi_nor_initialize(void) -{ - uint8_t vendor_id; -#ifdef CONFIG_FS_LITTLEFS - FAR struct mtd_dev_s *mtd_dev = &g_flexspi_nor.mtd; - int ret = -1; -#endif - /* Configure multiplexed pins as connected on the board */ - - imxrt_config_gpio(GPIO_FLEXSPI_DQS); - imxrt_config_gpio(GPIO_FLEXSPI_CS); - imxrt_config_gpio(GPIO_FLEXSPI_IO0); - imxrt_config_gpio(GPIO_FLEXSPI_IO1); - imxrt_config_gpio(GPIO_FLEXSPI_IO2); - imxrt_config_gpio(GPIO_FLEXSPI_IO3); - imxrt_config_gpio(GPIO_FLEXSPI_SCK); - - g_flexspi_nor.flexspi = imxrt_flexspi_initialize(0); - if (!g_flexspi_nor.flexspi) - { - return -1; - } - - FLEXSPI_SET_DEVICE_CONFIG(g_flexspi_nor.flexspi, - g_flexspi_nor.config, - g_flexspi_nor.port); - FLEXSPI_UPDATE_LUT(g_flexspi_nor.flexspi, - 0, - (const uint32_t *)g_flexspi_nor_lut, - sizeof(g_flexspi_nor_lut) / 4); - FLEXSPI_SOFTWARE_RESET(g_flexspi_nor.flexspi); - - if (imxrt_flexspi_nor_get_vendor_id(&g_flexspi_nor, &vendor_id)) - { - return -EIO; - } - - if (imxrt_flexspi_nor_enable_quad_mode(&g_flexspi_nor)) - { - return -EIO; - } - -#ifdef CONFIG_FS_LITTLEFS - /* Register the MTD driver so that it can be accessed from the - * VFS. - */ - - ret = register_mtddriver("/dev/nor", mtd_dev, 0755, NULL); - if (ret < 0) - { - syslog(LOG_ERR, "ERROR: Failed to register MTD driver: %d\n", - ret); - } - - /* mtd_dev->ioctl(mtd_dev, MTDIOC_BULKERASE, 0); */ - - /* Mount the LittleFS file system */ - - ret = nx_mount("/dev/nor", "/mnt/lfs", "littlefs", 0, - "autoformat"); - if (ret < 0) - { - syslog(LOG_ERR, - "ERROR: Failed to mount LittleFS at /mnt/lfs: %d\n", - ret); - } -#endif - - return 0; -} - -#endif /* CONFIG_IMXRT_FLEXSPI */ diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index dc72051c2e8..986f740ac56 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -655,25 +655,6 @@ config W25QXXXJV_SECTOR512 endif # MTD_W25QXXXJV -config MTD_FLEXSPI_NOR - bool "FlexSPI-based NOR FLASH" - default n - ---help--- - Support the W25Q064JV, WIS25WP064 - -if MTD_FLEXSPI_NOR - -config FLEXSPI_NOR_FREQUENCY - int "FlexSPI NOR Frequency" - default 133000000 - ---help--- - Per data sheet: - – 133MHz Single, Dual/Quad SPI clocks - – 266/532MHz equivalent Dual/Quad SPI - – 66MB/S continuous data transfer rate - -endif # MTD_FLEXSPI_NOR - config MTD_MX25RXX bool "QuadSPI-based Macronix MX25RXX family FLASH" default n diff --git a/drivers/mtd/Make.defs b/drivers/mtd/Make.defs index c18051cf9e0..32cdc7fbd5a 100644 --- a/drivers/mtd/Make.defs +++ b/drivers/mtd/Make.defs @@ -140,10 +140,6 @@ ifeq ($(CONFIG_MTD_IS25XP),y) CSRCS += is25xp.c endif -ifeq ($(CONFIG_MTD_FLEXSPI_NOR),y) -CSRCS += flexspi_nor.c -endif - ifeq ($(CONFIG_MTD_SMART),y) ifeq ($(CONFIG_FS_SMARTFS),y) CSRCS += smart.c diff --git a/drivers/mtd/flexspi_nor.c b/drivers/mtd/flexspi_nor.c deleted file mode 100644 index 7f3245809d6..00000000000 --- a/drivers/mtd/flexspi_nor.c +++ /dev/null @@ -1,647 +0,0 @@ -/**************************************************************************** - * drivers/mtd/flexspi_nor.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -/* Configuration ************************************************************/ - -#define NOR_PAGE_SIZE 0x0100U -#define NOR_SECTOR_SIZE 0x1000U - -/* This type represents the state of the MTD device. The struct mtd_dev_s - * must appear at the beginning of the definition so that you can freely - * cast between pointers to struct mtd_dev_s and struct flexspi_nor_dev_s. - */ - -struct flexspi_nor_dev_s -{ - struct mtd_dev_s mtd; - FAR struct flexspi_dev_s *flexspi; /* Saved FlexSPI interface instance */ - uint8_t *ahb_base; - enum flexspi_port_e port; - struct flexspi_device_config_s config; -}; - -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, -}; - -static const uint32_t flexspi_nor_lut[][4] = -{ - [READ_ID] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x9f, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_1PAD, 0x04), - }, - - [READ_STATUS_REG] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x05, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_1PAD, 0x04), - }, - - [WRITE_STATUS_REG] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x01, - FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_1PAD, 0x04), - }, - - [WRITE_ENABLE] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x06, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - - [ERASE_SECTOR] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x20, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - }, - - [ERASE_CHIP] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0xc7, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - - [READ_FAST_QUAD_OUTPUT] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x6b, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_DUMMY_SDR, FLEXSPI_4PAD, 0x08, - FLEXSPI_COMMAND_READ_SDR, FLEXSPI_4PAD, 0x04), - }, - - [PAGE_PROGRAM_QUAD_INPUT] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x32, - FLEXSPI_COMMAND_RADDR_SDR, FLEXSPI_1PAD, 0x18), - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_WRITE_SDR, FLEXSPI_4PAD, 0x04, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, - - [ENTER_QPI] = - { - FLEXSPI_LUT_SEQ(FLEXSPI_COMMAND_SDR, FLEXSPI_1PAD, 0x35, - FLEXSPI_COMMAND_STOP, FLEXSPI_1PAD, 0), - }, -}; - -static int flexspi_nor_get_vendor_id(const struct flexspi_nor_dev_s *dev, - uint8_t *vendor_id) -{ - uint32_t buffer = 0; - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_READ, - .seq_number = 1, - .seq_index = READ_ID, - .data = &buffer, - .data_size = 1, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - *vendor_id = buffer; - - return 0; -} - -static int flexspi_nor_read_status(const struct flexspi_nor_dev_s *dev, - uint32_t *status) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_READ, - .seq_number = 1, - .seq_index = READ_STATUS_REG, - .data = status, - .data_size = 1, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int flexspi_nor_write_status(const struct flexspi_nor_dev_s *dev, - uint32_t *status) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_WRITE, - .seq_number = 1, - .seq_index = WRITE_STATUS_REG, - .data = status, - .data_size = 1, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int flexspi_nor_write_enable(const struct flexspi_nor_dev_s *dev) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_COMMAND, - .seq_number = 1, - .seq_index = WRITE_ENABLE, - .data = NULL, - .data_size = 0, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int flexspi_nor_erase_sector(const struct flexspi_nor_dev_s *dev, - off_t offset) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = offset, - .port = dev->port, - .cmd_type = FLEXSPI_COMMAND, - .seq_number = 1, - .seq_index = ERASE_SECTOR, - .data = NULL, - .data_size = 0, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int flexspi_nor_erase_chip(const struct flexspi_nor_dev_s *dev) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = 0, - .port = dev->port, - .cmd_type = FLEXSPI_COMMAND, - .seq_number = 1, - .seq_index = ERASE_CHIP, - .data = NULL, - .data_size = 0, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int flexspi_nor_page_program(const struct flexspi_nor_dev_s *dev, - off_t offset, const void *buffer, size_t len) -{ - int stat; - - struct flexspi_transfer_s transfer = - { - .device_address = offset, - .port = dev->port, - .cmd_type = FLEXSPI_WRITE, - .seq_number = 1, - .seq_index = PAGE_PROGRAM_QUAD_INPUT, - .data = (uint32_t *) buffer, - .data_size = len, - }; - - stat = FLEXSPI_TRANSFER(dev->flexspi, &transfer); - if (stat != 0) - { - return -EIO; - } - - return 0; -} - -static int flexspi_nor_wait_bus_busy(const struct flexspi_nor_dev_s *dev) -{ - uint32_t status = 0; - int ret; - - do - { - ret = flexspi_nor_read_status(dev, &status); - if (ret) - { - return ret; - } - } - while (status & 1); - - return 0; -} - -static int flexspi_nor_enable_quad_mode(const struct flexspi_nor_dev_s *dev) -{ - uint32_t status = 0x40; - - flexspi_nor_write_status(dev, &status); - flexspi_nor_wait_bus_busy(dev); - FLEXSPI_SOFTWARE_RESET(dev->flexspi); - - return 0; -} - -static ssize_t flexspi_nor_read(FAR struct mtd_dev_s *dev, - off_t offset, - size_t nbytes, - FAR uint8_t *buffer) -{ - FAR struct flexspi_nor_dev_s *priv = (FAR struct flexspi_nor_dev_s *)dev; - uint8_t *src; - - finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); - - if (priv->port >= FLEXSPI_PORT_COUNT) - { - return -EIO; - } - - src = priv->ahb_base + offset; - - memcpy(buffer, src, nbytes); - - finfo("return nbytes: %d\n", (int)nbytes); - return (ssize_t)nbytes; -} - -static ssize_t flexspi_nor_bread(FAR struct mtd_dev_s *dev, off_t startblock, - size_t nblocks, FAR uint8_t *buffer) -{ - ssize_t nbytes; - - finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - - /* On this device, we can handle the block read just like the byte-oriented - * read - */ - - nbytes = flexspi_nor_read(dev, startblock * NOR_PAGE_SIZE, - nblocks * NOR_PAGE_SIZE, buffer); - if (nbytes > 0) - { - nbytes /= NOR_PAGE_SIZE; - } - - return nbytes; -} - -static ssize_t flexspi_nor_bwrite(FAR struct mtd_dev_s *dev, - off_t startblock, size_t nblocks, - FAR const uint8_t *buffer) -{ - FAR struct flexspi_nor_dev_s *priv = (FAR struct flexspi_nor_dev_s *)dev; - size_t len = nblocks * NOR_PAGE_SIZE; - off_t offset = startblock * NOR_PAGE_SIZE; - uint8_t *src = (uint8_t *) buffer; - uint8_t *dst = priv->ahb_base + startblock * NOR_PAGE_SIZE; - int i; - - finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - - while (len) - { - i = MIN(NOR_PAGE_SIZE, len); - flexspi_nor_write_enable(priv); - flexspi_nor_page_program(priv, offset, src, i); - flexspi_nor_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); - offset += i; - len -= i; - } - -#ifdef CONFIG_ARMV7M_DCACHE - up_invalidate_dcache((uintptr_t)dst, - (uintptr_t)dst + nblocks * NOR_PAGE_SIZE); -#endif - - return nblocks; -} - -static int flexspi_nor_erase(FAR struct mtd_dev_s *dev, off_t startblock, - size_t nblocks) -{ - FAR struct flexspi_nor_dev_s *priv = (FAR struct flexspi_nor_dev_s *)dev; - size_t blocksleft = nblocks; - uint8_t *dst = priv->ahb_base + startblock * NOR_SECTOR_SIZE; - - finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - - while (blocksleft-- > 0) - { - /* Erase each sector */ - - flexspi_nor_write_enable(priv); - flexspi_nor_erase_sector(priv, startblock * NOR_SECTOR_SIZE); - flexspi_nor_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); - startblock++; - } - -#ifdef CONFIG_ARMV7M_DCACHE - up_invalidate_dcache((uintptr_t)dst, - (uintptr_t)dst + nblocks * NOR_SECTOR_SIZE); -#endif - - return (int)nblocks; -} - -static int flexspi_nor_ioctl(FAR struct mtd_dev_s *dev, - int cmd, - unsigned long arg) -{ - FAR struct flexspi_nor_dev_s *priv = (FAR struct flexspi_nor_dev_s *)dev; - int ret = -EINVAL; /* Assume good command with bad parameters */ - - finfo("cmd: %d \n", cmd); - - switch (cmd) - { - case MTDIOC_GEOMETRY: - { - FAR struct mtd_geometry_s *geo = - (FAR struct mtd_geometry_s *)((uintptr_t)arg); - - if (geo) - { - /* Populate the geometry structure with information need to - * know the capacity and how to access the device. - * - * NOTE: - * that the device is treated as though it where just an array - * of fixed size blocks. That is most likely not true, but the - * client will expect the device logic to do whatever is - * necessary to make it appear so. - */ - - geo->blocksize = (NOR_PAGE_SIZE); - geo->erasesize = (NOR_SECTOR_SIZE); - geo->neraseblocks = 2048; /* 8MB only */ - - ret = OK; - - finfo("blocksize: %lu erasesize: %lu neraseblocks: %lu\n", - geo->blocksize, geo->erasesize, geo->neraseblocks); - } - } - break; - - case MTDIOC_BULKERASE: - { - /* Erase the entire device */ - - flexspi_nor_write_enable(priv); - flexspi_nor_erase_chip(priv); - flexspi_nor_wait_bus_busy(priv); - FLEXSPI_SOFTWARE_RESET(priv->flexspi); - } - break; - - case MTDIOC_PROTECT: - - /* TODO */ - - break; - - case MTDIOC_UNPROTECT: - - /* TODO */ - - break; - - default: - ret = -ENOTTY; /* Bad/unsupported command */ - break; - } - - finfo("return %d\n", ret); - return ret; -} - -static int flexspi_nor_init(const struct flexspi_nor_dev_s *dev) -{ - uint8_t vendor_id; - struct flexspi_device_config_s device_config; - - if (dev->port >= FLEXSPI_PORT_COUNT) - { - return -EINVAL; - } - - device_config.flexspi_root_clk = 120000000; - device_config.flash_size = 8192; - device_config.cs_interval_unit = FLEXSPI_CS_INTERVAL_UNIT1_SCK_CYCLE; - device_config.cs_interval = 0; - device_config.cs_hold_time = 3; - device_config.cs_setup_time = 3; - device_config.data_valid_time = 0; - device_config.columnspace = 0; - device_config.enable_word_address = 0; - device_config.awr_seq_index = 0; - device_config.awr_seq_number = 0; - device_config.ard_seq_index = READ_FAST_QUAD_OUTPUT; - device_config.ard_seq_number = 1; - device_config.ahb_write_wait_unit = FLEXSPI_AHB_WRITE_WAIT_UNIT2_AHB_CYCLE; - device_config.ahb_write_wait_interval = 0; - - FLEXSPI_SET_DEVICE_CONFIG(dev->flexspi, - (struct flexspi_device_config_s *) &device_config, - dev->port); - FLEXSPI_UPDATE_LUT(dev->flexspi, 0, (const uint32_t *)flexspi_nor_lut, - sizeof(flexspi_nor_lut) / 4); - FLEXSPI_SOFTWARE_RESET(dev->flexspi); - - if (flexspi_nor_get_vendor_id(dev, &vendor_id)) - { - return -EIO; - } - - if (flexspi_nor_enable_quad_mode(dev)) - { - return -EIO; - } - - return 0; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: flexspi_nor_initialize - * - * Description: - * Create an initialize MTD device instance for the FlexSPI-based NOR - * FLASH part. - * - * MTD devices are not registered in the file system, but are created as - * instances that can be bound to other functions (such as a block or - * character driver front end). - * - ****************************************************************************/ - -FAR struct mtd_dev_s *flexspi_nor_initialize(struct flexspi_dev_s *flexspi, - bool unprotect) -{ - FAR struct flexspi_nor_dev_s *priv; - int ret; - - finfo("flexspi: %p\n", flexspi); - DEBUGASSERT(flexspi != NULL); - - /* Allocate a state structure (we allocate the structure instead of using - * a fixed, static allocation so that we can handle multiple FLASH devices. - * The current implementation would handle only one FLASH part per FlexSPI - * device (only because of the FLEXSPI_DEV_FLASH(0) definition) and so - * would have to be extended to handle multiple FLASH parts on the same - * FlexSPI bus. - */ - - priv = (FAR struct flexspi_nor_dev_s *) - kmm_zalloc(sizeof(struct flexspi_nor_dev_s)); - if (priv) - { - /* Initialize the allocated structure (unsupported methods were - * nullified by kmm_zalloc). - */ - - priv->mtd.erase = flexspi_nor_erase; - priv->mtd.bread = flexspi_nor_bread; - priv->mtd.bwrite = flexspi_nor_bwrite; - priv->mtd.read = flexspi_nor_read; - priv->mtd.ioctl = flexspi_nor_ioctl; - priv->mtd.name = "flexspi_nor"; - priv->flexspi = flexspi; - priv->ahb_base = (uint8_t *) 0x60000000; - priv->port = FLEXSPI_PORT_A1; - - ret = flexspi_nor_init(priv); - if (ret != OK) - { - /* Unrecognized! Discard all of that work we just did and - * return NULL - */ - - ferr("ERROR Unrecognized FlexSPI NOR device\n"); - goto errout_with_priv; - } - } - - /* Return the implementation-specific state structure as the MTD device */ - - finfo("Return %p\n", priv); - return (FAR struct mtd_dev_s *)priv; - -errout_with_priv: - kmm_free(priv); - return NULL; -} diff --git a/include/nuttx/mtd/mtd.h b/include/nuttx/mtd/mtd.h index 85435667453..32e1314113b 100644 --- a/include/nuttx/mtd/mtd.h +++ b/include/nuttx/mtd/mtd.h @@ -91,7 +91,6 @@ ****************************************************************************/ struct qspi_dev_s; /* Forward reference */ -struct flexspi_dev_s; /* Forward reference */ /* The following defines the geometry for the device. It treats the device * as though it were just an array of fixed size blocks. That is most likely @@ -595,18 +594,6 @@ FAR struct mtd_dev_s *n25qxxx_initialize(FAR struct qspi_dev_s *qspi, FAR struct mtd_dev_s *w25qxxxjv_initialize(FAR struct qspi_dev_s *qspi, bool unprotect); -/**************************************************************************** - * Name: flexspi_nor_initialize - * - * Description: - * Create an initialized MTD device instance for the FlexSPI-based - * FLASH part. - * - ****************************************************************************/ - -FAR struct mtd_dev_s *flexspi_nor_initialize(FAR struct flexspi_dev_s - *flexspi, bool unprotect); - /**************************************************************************** * Name: blockmtd_initialize * diff --git a/include/nuttx/spi/flexspi.h b/include/nuttx/spi/flexspi.h deleted file mode 100644 index 257b76f2cf8..00000000000 --- a/include/nuttx/spi/flexspi.h +++ /dev/null @@ -1,521 +0,0 @@ -/**************************************************************************** - * include/nuttx/spi/flexspi.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __INCLUDE_NUTTX_SPI_FLEXSPI_H -#define __INCLUDE_NUTTX_SPI_FLEXSPI_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Configuration ************************************************************/ - -/* LUT - LUT 0..LUT 63 */ - -#define FLEXSPI_LUT_OPERAND0_MASK (0xffU) -#define FLEXSPI_LUT_OPERAND0_SHIFT (0U) - -/* OPERAND0 */ - -#define FLEXSPI_LUT_OPERAND0(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPERAND0_SHIFT)) & FLEXSPI_LUT_OPERAND0_MASK) -#define FLEXSPI_LUT_NUM_PADS0_MASK (0x300U) -#define FLEXSPI_LUT_NUM_PADS0_SHIFT (8U) - -/* NUM_PADS0 */ - -#define FLEXSPI_LUT_NUM_PADS0(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_NUM_PADS0_SHIFT)) & FLEXSPI_LUT_NUM_PADS0_MASK) -#define FLEXSPI_LUT_OPCODE0_MASK (0xfc00U) -#define FLEXSPI_LUT_OPCODE0_SHIFT (10U) - -/* OPCODE0 */ - -#define FLEXSPI_LUT_OPCODE0(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPCODE0_SHIFT)) & FLEXSPI_LUT_OPCODE0_MASK) -#define FLEXSPI_LUT_OPERAND1_MASK (0xff0000U) -#define FLEXSPI_LUT_OPERAND1_SHIFT (16U) - -/* OPERAND1 */ - -#define FLEXSPI_LUT_OPERAND1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPERAND1_SHIFT)) & FLEXSPI_LUT_OPERAND1_MASK) -#define FLEXSPI_LUT_NUM_PADS1_MASK (0x3000000U) -#define FLEXSPI_LUT_NUM_PADS1_SHIFT (24U) - -/* NUM_PADS1 - NUM_PADS1 */ - -#define FLEXSPI_LUT_NUM_PADS1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_NUM_PADS1_SHIFT)) & FLEXSPI_LUT_NUM_PADS1_MASK) -#define FLEXSPI_LUT_OPCODE1_MASK (0xfc000000U) -#define FLEXSPI_LUT_OPCODE1_SHIFT (26U) - -/* OPCODE1 */ - -#define FLEXSPI_LUT_OPCODE1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPCODE1_SHIFT)) & FLEXSPI_LUT_OPCODE1_MASK) - -/* Formula to form FLEXSPI instructions in LUT table */ - -#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ - (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | \ - FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ - FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) - -/* Access macros ************************************************************/ - -/**************************************************************************** - * Name: FLEXSPI_LOCK - * - * Description: - * On FlexSPI buses where there are multiple devices, it will be necessary - * to lock FlexSPI to have exclusive access to the buses for a sequence of - * transfers. The bus should be locked before the chip is selected. - * - * Input Parameters: - * dev - Device-specific state data - * lock - true: Lock FlexSPI bus, false: unlock FlexSPI bus - * - * Returned Value: - * None - * - ****************************************************************************/ - -#define FLEXSPI_LOCK(d,l) (d)->ops->lock(d,l) - -/**************************************************************************** - * Name: FLEXSPI_TRANSFER - * - * Description: - * Perform one FlexSPI transfer - * - * Input Parameters: - * dev - Device-specific state data - * xfer - Describes the transfer to be performed. - * - * Returned Value: - * 0 on SUCCESS, STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT, - * STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR or - * STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT otherwise - * - ****************************************************************************/ - -#define FLEXSPI_TRANSFER(d,x) (d)->ops->transfer_blocking(d,x) - -/**************************************************************************** - * Name: FLEXSPI_SOFTWARE_RESET - * - * Description: - * Perform FlexSPI software reset - * - * Input Parameters: - * dev - Device-specific state data - * - * Returned Value: - * none - * - ****************************************************************************/ - -#define FLEXSPI_SOFTWARE_RESET(d) (d)->ops->software_reset(d) - -/**************************************************************************** - * Name: FLEXSPI_UPDATE_LUT - * - * Description: - * Perform FlexSPI LUT table update - * - * Input Parameters: - * dev - Device-specific state data - * index - Index start to update - * cmd - Command array - * count - Size of the array - * - * Returned Value: - * none - * - ****************************************************************************/ - -#define FLEXSPI_UPDATE_LUT(d,i,c,n) (d)->ops->update_lut(d,i,c,n) - -/**************************************************************************** - * Name: FLEXSPI_SET_DEVICE_CONFIG - * - * Description: - * Perform FlexSPI device config - * - * Input Parameters: - * dev - Device-specific state data - * config - Config data for external device - * port - Port - * - * Returned Value: - * none - * - ****************************************************************************/ - -#define FLEXSPI_SET_DEVICE_CONFIG(d,c,p) (d)->ops->set_device_config(d,c,p) - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/* CMD definition of FLEXSPI, use to form LUT instruction, flexspi_command */ - -enum -{ - FLEXSPI_COMMAND_STOP = 0x00, /* Stop execution, deassert CS */ - FLEXSPI_COMMAND_SDR = 0x01, /* Transmit Command code to Flash, - * using SDR mode. - */ - - FLEXSPI_COMMAND_RADDR_SDR = 0x02, /* Transmit Row Address to Flash, - * using SDR mode. - */ - - FLEXSPI_COMMAND_CADDR_SDR = 0x03, /* Transmit Column Address to - * Flash, using SDR mode. - */ - - FLEXSPI_COMMAND_MODE1_SDR = 0x04, /* Transmit 1-bit Mode bits to - * Flash, using SDR mode. - */ - - FLEXSPI_COMMAND_MODE2_SDR = 0x05, /* Transmit 2-bit Mode bits to - * Flash, using SDR mode. - */ - - FLEXSPI_COMMAND_MODE4_SDR = 0x06, /* Transmit 4-bit Mode bits to - * Flash, using SDR mode. - */ - - FLEXSPI_COMMAND_MODE8_SDR = 0x07, /* Transmit 8-bit Mode bits to - * Flash, using SDR mode. - */ - - FLEXSPI_COMMAND_WRITE_SDR = 0x08, /* Transmit Programming Data to - * Flash, using SDR mode. - */ - - FLEXSPI_COMMAND_READ_SDR = 0x09, /* Receive Read Data from Flash, - * using SDR mode. - */ - - FLEXSPI_COMMAND_LEARN_SDR = 0x0a, /* Receive Read Data or Preamble - * bit from Flash, SDR mode. - */ - - FLEXSPI_COMMAND_DATSZ_SDR = 0x0b, /* Transmit Read/Program Data size - * (byte) to Flash, SDR mode. - */ - - FLEXSPI_COMMAND_DUMMY_SDR = 0x0c, /* Leave data lines undriven by - * FlexSPI controller. - */ - - FLEXSPI_COMMAND_DUMMY_RWDS_SDR = 0x0d, /* Leave data lines undriven by - * FlexSPI controller, dummy cycles - * decided by RWDS. - */ - - FLEXSPI_COMMAND_DDR = 0x21, /* Transmit Command code to Flash, - * using DDR mode. - */ - - FLEXSPI_COMMAND_RADDR_DDR = 0x22, /* Transmit Row Address to Flash, - * using DDR mode. - */ - - FLEXSPI_COMMAND_CADDR_DDR = 0x23, /* Transmit Column Address to - * Flash, using DDR mode. - */ - - FLEXSPI_COMMAND_MODE1_DDR = 0x24, /* Transmit 1-bit Mode bits to - * Flash, using DDR mode. - */ - - FLEXSPI_COMMAND_MODE2_DDR = 0x25, /* Transmit 2-bit Mode bits to - * Flash, using DDR mode. - */ - - FLEXSPI_COMMAND_MODE4_DDR = 0x26, /* Transmit 4-bit Mode bits to - * Flash, using DDR mode. - */ - - FLEXSPI_COMMAND_MODE8_DDR = 0x27, /* Transmit 8-bit Mode bits to - * Flash, using DDR mode. - */ - - FLEXSPI_COMMAND_WRITE_DDR = 0x28, /* Transmit Programming Data to - * Flash, using DDR mode. - */ - - FLEXSPI_COMMAND_READ_DDR = 0x29, /* Receive Read Data from Flash, - * using DDR mode. - */ - - FLEXSPI_COMMAND_LEARN_DDR = 0x2a, /* Receive Read Data or Preamble - * bit from Flash, DDR mode. - */ - - FLEXSPI_COMMAND_DATSZ_DDR = 0x2b, /* Transmit Read/Program Data size - * (byte) to Flash, DDR mode. - */ - - FLEXSPI_COMMAND_DUMMY_DDR = 0x2c, /* Leave data lines undriven by - * FlexSPI controller. - */ - - FLEXSPI_COMMAND_DUMMY_RWDS_DDR = 0x2d, /* Leave data lines undriven by - * FlexSPI controller, dummy cycles - * decided by RWDS. - */ - - FLEXSPI_COMMAND_JUMP_ON_CS = 0x1f, /* Stop execution, deassert CS and - * save operand[7:0] as the - * instruction start pointer for - * next sequence - */ -}; - -/* Pad definition of FLEXSPI, use to form LUT instruction */ - -enum flexspi_pad_e -{ - FLEXSPI_1PAD = 0x00, /* Transmit command/address and transmit/receive data - * only through DATA0/DATA1. - */ - - FLEXSPI_2PAD = 0x01, /* Transmit command/address and transmit/receive data - * only through DATA[1:0]. - */ - - FLEXSPI_4PAD = 0x02, /* Transmit command/address and transmit/receive data - * only through DATA[3:0]. - */ - - FLEXSPI_8PAD = 0x03, /* Transmit command/address and transmit/receive data - * only through DATA[7:0]. - */ -}; - -/* FLEXSPI operation port select */ - -enum flexspi_port_e -{ - FLEXSPI_PORT_A1 = 0x0, /* Access flash on A1 port */ - FLEXSPI_PORT_A2, /* Access flash on A2 port */ - FLEXSPI_PORT_B1, /* Access flash on B1 port */ - FLEXSPI_PORT_B2, /* Access flash on B2 port */ - FLEXSPI_PORT_COUNT -}; - -/* Command type */ - -enum flexspi_command_type_e -{ - FLEXSPI_COMMAND, /* FlexSPI operation: Only command, both TX and Rx buffer - * are ignored. - */ - - FLEXSPI_CONFIG, /* FlexSPI operation: Configure device mode, the TX fifo - * size is fixed in LUT. - */ - - FLEXSPI_READ, /* FlexSPI operation: Read, only Rx Buffer is - * effective. - */ - - FLEXSPI_WRITE, /* FlexSPI operation: Read, only Tx Buffer is - * effective. - */ -}; - -/* Status structure of FLEXSPI */ - -enum -{ - STATUS_FLEXSPI_BUSY = 0, /* FLEXSPI is busy */ - - STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT = 1, /* Sequence execution - * timeout error occurred - * during FLEXSPI transfer. - */ - - STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR = 2, /* IP command Sequence - * execution timeout error - * occurred during FLEXSPI - * transfer. - */ - - STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT = 3, /* IP command grant timeout - * error occurred during - * FLEXSPI transfer. - */ -}; - -/* Transfer structure for FLEXSPI */ - -struct flexspi_transfer_s -{ - uint32_t device_address; /* Operation device address */ - enum flexspi_port_e port; /* Operation port */ - enum flexspi_command_type_e cmd_type; /* Execution command type */ - uint8_t seq_index; /* Sequence ID for command */ - uint8_t seq_number; /* Sequence number for command */ - uint32_t *data; /* Data buffer */ - size_t data_size; /* Data size in bytes */ -}; - -/* FLEXSPI interval unit for flash device select */ - -enum flexspi_cs_interval_cycle_unit_e -{ - FLEXSPI_CS_INTERVAL_UNIT1_SCK_CYCLE = 0x0, /* Chip selection interval: - * CSINTERVAL * 1 serial - * clock cycle. - */ - - FLEXSPI_CS_INTERVAL_UNIT256_SCK_CYCLE = 0x1, /* Chip selection interval: - * CSINTERVAL * 256 serial - * clock cycle. - */ -}; - -/* FLEXSPI AHB wait interval unit for writing */ - -enum flexspi_ahb_write_wait_unit_e -{ - FLEXSPI_AHB_WRITE_WAIT_UNIT2_AHB_CYCLE = 0x0, /* AWRWAIT unit is 2 - * ahb clock cycle. - */ - - FLEXSPI_AHB_WRITE_WAIT_UNIT8_AHB_CYCLE = 0x1, /* AWRWAIT unit is 8 - * ahb clock cycle. - */ - - FLEXSPI_AHB_WRITE_WAIT_UNIT32_AHB_CYCLE = 0x2, /* AWRWAIT unit is 32 - * ahb clock cycle. - */ - - FLEXSPI_AHB_WRITE_WAIT_UNIT128_AHB_CYCLE = 0x3, /* AWRWAIT unit is 128 - * ahb clock cycle. - */ - - FLEXSPI_AHB_WRITE_WAIT_UNIT512_AHB_CYCLE = 0x4, /* AWRWAIT unit is 512 - * ahb clock cycle. - */ - - FLEXSPI_AHB_WRITE_WAIT_UNIT2048_AHB_CYCLE = 0x5, /* AWRWAIT unit is 2048 - * ahb clock cycle. - */ - - FLEXSPI_AHB_WRITE_WAIT_UNIT8192_AHB_CYCLE = 0x6, /* AWRWAIT unit is 8192 - * ahb clock cycle. - */ - - FLEXSPI_AHB_WRITE_WAIT_UNIT32768_AHB_CYCLE = 0x7, /* AWRWAIT unit is 32768 - * ahb clock cycle. - */ -}; - -/* External device configuration items */ - -struct flexspi_device_config_s -{ - uint32_t flexspi_root_clk; /* FLEXSPI serial root clock */ - bool is_sck2_enabled; /* FLEXSPI use SCK2 */ - uint32_t flash_size; /* Flash size in KByte */ - - enum flexspi_cs_interval_cycle_unit_e cs_interval_unit; /* CS interval unit, 1 - * or 256 cycle. - */ - - uint16_t cs_interval; /* CS line assert interval, multiply CS - * interval unit to get the CS line assert - * interval cycles. - */ - - uint8_t cs_hold_time; /* CS line hold time */ - uint8_t cs_setup_time; /* CS line setup time */ - uint8_t data_valid_time; /* Data valid time for external device */ - uint8_t columnspace; /* Column space size */ - bool enable_word_address; /* If enable word address */ - uint8_t awr_seq_index; /* Sequence ID for AHB write command */ - uint8_t awr_seq_number; /* Sequence number for AHB write command */ - uint8_t ard_seq_index; /* Sequence ID for AHB read command */ - uint8_t ard_seq_number; /* Sequence number for AHB read command */ - - enum flexspi_ahb_write_wait_unit_e ahb_write_wait_unit; /* AHB write wait unit */ - - uint16_t ahb_write_wait_interval; /* AHB write wait interval, multiply AHB - * write interval unit to get the AHB - * write wait cycles. - */ - - bool enable_write_mask; /* Enable/Disable FLEXSPI drive DQS pin as write mask - * when writing to external device. - */ -}; - -/* The FlexSPI vtable */ - -struct flexspi_dev_s; -struct flexspi_ops_s -{ - CODE int (*lock)(FAR struct flexspi_dev_s *dev, bool lock); - CODE int (*transfer_blocking)(FAR struct flexspi_dev_s *dev, - FAR struct flexspi_transfer_s *xfer); - CODE void (*software_reset)(FAR struct flexspi_dev_s *dev); - CODE void (*update_lut)(FAR struct flexspi_dev_s *dev, - uint32_t index, const uint32_t *cmd, - uint32_t count); - CODE void (*set_device_config)(FAR struct flexspi_dev_s *dev, - FAR struct flexspi_device_config_s *config, - enum flexspi_port_e port); -}; - -/* FlexSPI private data. This structure only defines the initial fields of - * the structure visible to the FlexSPI client. The specific implementation - * may add additional, device specific fields - */ - -struct flexspi_dev_s -{ - FAR const struct flexspi_ops_s *ops; -}; - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -#undef EXTERN -#if defined(__cplusplus) -} -#endif -#endif /* __INCLUDE_NUTTX_SPI_FLEXSPI_H */