You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
4.6 KiB
248 lines
4.6 KiB
/* |
|
* Copyright (c) 2025 Nordic Semiconductor ASA |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#ifndef __FLASH_MSPI_NOR_H__ |
|
#define __FLASH_MSPI_NOR_H__ |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
#include <zephyr/drivers/flash.h> |
|
#include <zephyr/drivers/mspi.h> |
|
#include "jesd216.h" |
|
#include "spi_nor.h" |
|
|
|
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) |
|
#define WITH_RESET_GPIO 1 |
|
#endif |
|
|
|
struct flash_mspi_nor_config { |
|
const struct device *bus; |
|
uint32_t flash_size; |
|
struct mspi_dev_id mspi_id; |
|
struct mspi_dev_cfg mspi_nor_cfg; |
|
struct mspi_dev_cfg mspi_nor_init_cfg; |
|
enum mspi_dev_cfg_mask mspi_nor_cfg_mask; |
|
#if defined(CONFIG_MSPI_XIP) |
|
struct mspi_xip_cfg xip_cfg; |
|
#endif |
|
#if defined(WITH_RESET_GPIO) |
|
struct gpio_dt_spec reset; |
|
uint32_t reset_pulse_us; |
|
uint32_t reset_recovery_us; |
|
#endif |
|
#if defined(CONFIG_FLASH_PAGE_LAYOUT) |
|
struct flash_pages_layout layout; |
|
#endif |
|
uint8_t jedec_id[SPI_NOR_MAX_ID_LEN]; |
|
const struct flash_mspi_nor_cmds *jedec_cmds; |
|
struct flash_mspi_nor_quirks *quirks; |
|
uint8_t dw15_qer; |
|
}; |
|
|
|
struct flash_mspi_nor_data { |
|
struct k_sem acquired; |
|
struct mspi_xfer_packet packet; |
|
struct mspi_xfer xfer; |
|
struct mspi_dev_cfg *curr_cfg; |
|
}; |
|
|
|
struct flash_mspi_nor_cmd { |
|
enum mspi_xfer_direction dir; |
|
uint32_t cmd; |
|
uint16_t tx_dummy; |
|
uint16_t rx_dummy; |
|
uint8_t cmd_length; |
|
uint8_t addr_length; |
|
bool force_single; |
|
}; |
|
|
|
struct flash_mspi_nor_cmds { |
|
struct flash_mspi_nor_cmd id; |
|
struct flash_mspi_nor_cmd write_en; |
|
struct flash_mspi_nor_cmd read; |
|
struct flash_mspi_nor_cmd status; |
|
struct flash_mspi_nor_cmd config; |
|
struct flash_mspi_nor_cmd page_program; |
|
struct flash_mspi_nor_cmd sector_erase; |
|
struct flash_mspi_nor_cmd chip_erase; |
|
struct flash_mspi_nor_cmd sfdp; |
|
}; |
|
|
|
const struct flash_mspi_nor_cmds commands_single = { |
|
.id = { |
|
.dir = MSPI_RX, |
|
.cmd = JESD216_CMD_READ_ID, |
|
.cmd_length = 1, |
|
}, |
|
.write_en = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_CMD_WREN, |
|
.cmd_length = 1, |
|
}, |
|
.read = { |
|
.dir = MSPI_RX, |
|
.cmd = SPI_NOR_CMD_READ_FAST, |
|
.cmd_length = 1, |
|
.addr_length = 3, |
|
.rx_dummy = 8, |
|
}, |
|
.status = { |
|
.dir = MSPI_RX, |
|
.cmd = SPI_NOR_CMD_RDSR, |
|
.cmd_length = 1, |
|
}, |
|
.config = { |
|
.dir = MSPI_RX, |
|
.cmd = SPI_NOR_CMD_RDCR, |
|
.cmd_length = 1, |
|
}, |
|
.page_program = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_CMD_PP, |
|
.cmd_length = 1, |
|
.addr_length = 3, |
|
}, |
|
.sector_erase = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_CMD_SE, |
|
.cmd_length = 1, |
|
.addr_length = 3, |
|
}, |
|
.chip_erase = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_CMD_CE, |
|
.cmd_length = 1, |
|
}, |
|
.sfdp = { |
|
.dir = MSPI_RX, |
|
.cmd = JESD216_CMD_READ_SFDP, |
|
.cmd_length = 1, |
|
.addr_length = 3, |
|
.rx_dummy = 8, |
|
}, |
|
}; |
|
|
|
const struct flash_mspi_nor_cmds commands_quad_1_4_4 = { |
|
.id = { |
|
.dir = MSPI_RX, |
|
.cmd = JESD216_CMD_READ_ID, |
|
.cmd_length = 1, |
|
.force_single = true, |
|
}, |
|
.write_en = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_CMD_WREN, |
|
.cmd_length = 1, |
|
}, |
|
.read = { |
|
.dir = MSPI_RX, |
|
.cmd = SPI_NOR_CMD_4READ, |
|
.cmd_length = 1, |
|
.addr_length = 3, |
|
.rx_dummy = 6, |
|
}, |
|
.status = { |
|
.dir = MSPI_RX, |
|
.cmd = SPI_NOR_CMD_RDSR, |
|
.cmd_length = 1, |
|
.force_single = true, |
|
}, |
|
.config = { |
|
.dir = MSPI_RX, |
|
.cmd = SPI_NOR_CMD_RDCR, |
|
.cmd_length = 1, |
|
.force_single = true, |
|
}, |
|
.page_program = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_CMD_PP_1_4_4, |
|
.cmd_length = 1, |
|
.addr_length = 3, |
|
}, |
|
.sector_erase = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_CMD_SE, |
|
.cmd_length = 1, |
|
.addr_length = 3, |
|
.force_single = true, |
|
}, |
|
.chip_erase = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_CMD_CE, |
|
.cmd_length = 1, |
|
}, |
|
.sfdp = { |
|
.dir = MSPI_RX, |
|
.cmd = JESD216_CMD_READ_SFDP, |
|
.cmd_length = 1, |
|
.addr_length = 3, |
|
.rx_dummy = 8, |
|
.force_single = true, |
|
}, |
|
}; |
|
|
|
const struct flash_mspi_nor_cmds commands_octal = { |
|
.id = { |
|
.dir = MSPI_RX, |
|
.cmd = JESD216_OCMD_READ_ID, |
|
.cmd_length = 2, |
|
.addr_length = 4, |
|
.rx_dummy = 4 |
|
}, |
|
.write_en = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_OCMD_WREN, |
|
.cmd_length = 2, |
|
}, |
|
.read = { |
|
.dir = MSPI_RX, |
|
.cmd = SPI_NOR_OCMD_RD, |
|
.cmd_length = 2, |
|
.addr_length = 4, |
|
.rx_dummy = 20, |
|
}, |
|
.status = { |
|
.dir = MSPI_RX, |
|
.cmd = SPI_NOR_OCMD_RDSR, |
|
.cmd_length = 2, |
|
.addr_length = 4, |
|
.rx_dummy = 4, |
|
}, |
|
.page_program = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_OCMD_PAGE_PRG, |
|
.cmd_length = 2, |
|
.addr_length = 4, |
|
}, |
|
.sector_erase = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_OCMD_SE, |
|
.cmd_length = 2, |
|
.addr_length = 4, |
|
}, |
|
.chip_erase = { |
|
.dir = MSPI_TX, |
|
.cmd = SPI_NOR_OCMD_CE, |
|
.cmd_length = 2, |
|
}, |
|
.sfdp = { |
|
.dir = MSPI_RX, |
|
.cmd = JESD216_OCMD_READ_SFDP, |
|
.cmd_length = 2, |
|
.addr_length = 4, |
|
.rx_dummy = 20, |
|
}, |
|
}; |
|
|
|
void flash_mspi_command_set(const struct device *dev, const struct flash_mspi_nor_cmd *cmd); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#endif /*__FLASH_MSPI_NOR_H__*/
|
|
|