Skip to content

Commit

Permalink
drivers: flash: mspi nor flash device memory functions
Browse files Browse the repository at this point in the history
This commit adds a reset and jedec
commands and a memory configuration io_mode/data_rate
sent to the NOR flash device through the controller.

Signed-off-by: Francois Ramu <[email protected]>
  • Loading branch information
FRASTM committed Sep 12, 2024
1 parent 3e8ab20 commit f5a2e2f
Showing 1 changed file with 70 additions and 40 deletions.
110 changes: 70 additions & 40 deletions drivers/flash/flash_mspi_nor_mx.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct flash_mspi_nor_mx_data {
struct mspi_xfer_packet packet;

struct k_sem lock;
uint32_t jedec_id;
uint8_t jedec_id[JESD216_READ_ID_LEN];
};

static bool flash_mspi_nor_mx_address_is_valid(const struct device *dev, off_t addr,
Expand Down Expand Up @@ -214,9 +214,6 @@ static int flash_mspi_nor_mx_write_enable(const struct device *flash)
/* Initialize the write enable command */
ret = flash_mspi_nor_mx_command_write(flash, SPI_NOR_CMD_WREN, 0, 0, 0, NULL, 0);

/* New command to Configure automatic polling mode to wait for write enabling */
ret = flash_mspi_nor_mx_command_write(flash, SPI_NOR_CMD_RDSR, 0, 0, 0, NULL, 0);

/* Wait for auto-polling bit */

return ret;
Expand All @@ -229,16 +226,16 @@ static int flash_mspi_nor_mx_write_disable(const struct device *flash)
LOG_DBG("Disabling write");
ret = flash_mspi_nor_mx_command_write(flash, SPI_NOR_CMD_WRDI, 0, 0, 0, NULL, 0);

return ret;
// return ret;
}

static int flash_mspi_nor_mx_reset(const struct device *flash)
{
int ret;

/* TODO : reset by gpio pin :set pi, wait duration, release pin */

/* Send Reset enable then reset Mem */
LOG_DBG("Resetting ");
/* Send Reset enable then reset Mem use the SPI/STR command */
ret = flash_mspi_nor_mx_command_write(flash, SPI_NOR_CMD_RESET_EN, 0, 0, 0, NULL, 0);
if (ret) {
return ret;
Expand All @@ -254,19 +251,29 @@ static int flash_mspi_nor_mx_reset(const struct device *flash)
static int flash_mspi_nor_mx_get_vendor_id(const struct device *flash, uint8_t *vendor_id)
{
struct flash_mspi_nor_mx_data *data = flash->data;
uint8_t buffer[11];
uint8_t buffer[JESD216_READ_ID_LEN];
int ret;

if (vendor_id == NULL) {
return -EINVAL;
}

LOG_DBG("Reading id");
/* Read 11 bytes from flash */
ret = flash_mspi_nor_mx_command_read(flash, SPI_NOR_CMD_RDID, 0, 0, 0, buffer, 11);
*vendor_id = buffer[7];

data->jedec_id = (buffer[7] << 16) | (buffer[8] << 8) | buffer[9];
/* Read bytes from flash : use the SPI/STR command */
ret = flash_mspi_nor_mx_command_read(flash, SPI_NOR_CMD_RDID, 0, 0,
data->dev_cfg.rx_dummy,
buffer,
JESD216_READ_ID_LEN);
if (ret) {
return ret;
}

memcpy(data->jedec_id, buffer, JESD216_READ_ID_LEN);
*vendor_id = data->jedec_id[0];

LOG_DBG("Jedec ID = [%02x %02x %02x]",
data->jedec_id[0], data->jedec_id[1], data->jedec_id[2]);

return ret;
}
Expand All @@ -287,8 +294,8 @@ static int flash_mspi_nor_mx_erase_sector(const struct device *flash, off_t addr
int ret;

LOG_DBG("Erasing sector at 0x%08zx", (ssize_t)addr);

ret = flash_mspi_nor_mx_command_write(flash, SPI_NOR_CMD_SE, addr, 4, 0, NULL, 0);
/* Instruction SPI_NOR_CMD_SE is also accepted */
ret = flash_mspi_nor_mx_command_write(flash, SPI_NOR_CMD_SE_4B, addr, 4, 0, NULL, 0);

return ret;
}
Expand Down Expand Up @@ -420,6 +427,7 @@ static int flash_mspi_nor_mx_read(const struct device *flash, off_t offset, void
return -EINVAL;
}

LOG_DBG("Flash : read %d Bytes at x%08zx", size, offset);
acquire(flash);

/* During the MemoryMapped, read with a memcopy */
Expand All @@ -441,8 +449,9 @@ static int flash_mspi_nor_mx_read(const struct device *flash, off_t offset, void
data->packet.num_bytes = size;

data->trans.async = true; /* use callback on Irq if PIO, meaningless with DMA */
data->trans.xfer_mode = MSPI_DMA;
data->trans.rx_dummy = data->dev_cfg.rx_dummy;
data->trans.xfer_mode = MSPI_PIO; /* TODO : transfer with DMA */
data->trans.rx_dummy = 0; /* TODO set data->dev_cfg.rx_dummy; depending on the command */

data->trans.cmd_length = data->dev_cfg.cmd_length;
data->trans.addr_length = data->dev_cfg.addr_length;
data->trans.hold_ce = false;
Expand All @@ -465,7 +474,7 @@ static int flash_mspi_nor_mx_read(const struct device *flash, off_t offset, void
return ret;
}

/* Function to write the flash (page program) : with possible PIO IT or DMA */
/* Function to write the flash (page program) : with possible PIO IT (ASYNC) or DMA */
static int flash_mspi_nor_mx_write(const struct device *flash, off_t offset, const void *wdata,
size_t size)
{
Expand All @@ -486,6 +495,8 @@ static int flash_mspi_nor_mx_write(const struct device *flash, off_t offset, con
return -EINVAL;
}

LOG_DBG("Flash : write %d Bytes at x%08zx", size, offset);

acquire(flash);

/* Cannot write during MemoryMapped, first disable */
Expand Down Expand Up @@ -615,16 +626,16 @@ static int flash_mspi_nor_mx_erase(const struct device *flash, off_t offset, siz
}

ret = flash_mspi_nor_mx_unprotect_sector(flash, offset);
if (ret) {
goto erase_end;
}

LOG_DBG("Flash : erase block %d", 1 + (offset % SPI_NOR_BLOCK_SIZE));

ret = flash_mspi_nor_mx_write_enable(flash);
if (ret) {
goto erase_end;
}

ret = flash_mspi_nor_mx_erase_block(flash, offset);

if (ret) {
goto erase_end;
}
Expand All @@ -644,10 +655,8 @@ static int flash_mspi_nor_mx_erase(const struct device *flash, off_t offset, siz
}

ret = flash_mspi_nor_mx_unprotect_sector(flash, offset);
if (ret) {
goto erase_end;
}

LOG_DBG("Flash : erase sector %d", 1 + (offset % SPI_NOR_SECTOR_SIZE));
ret = flash_mspi_nor_mx_write_enable(flash);
if (ret) {
goto erase_end;
Expand Down Expand Up @@ -714,15 +723,27 @@ static int flash_mspi_nor_mx_init(const struct device *flash)
return -EIO;
}

switch (cfg->tar_dev_cfg.data_rate) {
case MSPI_DATA_RATE_SINGLE:
case MSPI_DATA_RATE_DUAL:
break;
default:
LOG_ERR("MSPI bus data rate %d not supported", cfg->tar_dev_cfg.data_rate);
return -EIO;
}

/* The SPI/DTR is not a valid config of data_mode/data_rate according to the DTS */
if ((cfg->tar_dev_cfg.io_mode == MSPI_IO_MODE_SINGLE)
&& (cfg->tar_dev_cfg.data_rate == MSPI_DATA_RATE_DUAL)) {
LOG_ERR("MSPI data rate SPI/DTR is not valid");
return -EIO;
}

if (mspi_dev_config(cfg->bus, &cfg->dev_id, MSPI_DEVICE_CONFIG_ALL, &cfg->serial_cfg)) {
LOG_ERR("Failed to config mspi controller");;
/* At this time only set the io_mode and data rate */
if (mspi_dev_config(cfg->bus, &cfg->dev_id,
(MSPI_DEVICE_CONFIG_IO_MODE|MSPI_DEVICE_CONFIG_DATA_RATE),
&cfg->serial_cfg)) {
LOG_ERR("Failed to config mspi controller");
return -EIO;
}
data->dev_cfg = cfg->serial_cfg;
Expand All @@ -740,6 +761,16 @@ static int flash_mspi_nor_mx_init(const struct device *flash)
}
LOG_DBG("Vendor id: 0x%0x", vendor_id);

/*
* We should check here that the mem is ready,
* configure it according to the io-mode/data-rate
*/
if (mspi_dev_config(cfg->bus, &cfg->dev_id, MSPI_DEVICE_CONFIG_ALL, &cfg->tar_dev_cfg)) {
LOG_ERR("Failed to config mspi controller");;
return -EIO;
}
LOG_DBG("Flash config'd");
#if 0
if (flash_mspi_nor_mx_write_enable(flash)) {
return -EIO;
}
Expand All @@ -748,16 +779,6 @@ static int flash_mspi_nor_mx_init(const struct device *flash)
return -EIO;
}

uint8_t cmd;

if (cfg->tar_dev_cfg.io_mode == MSPI_IO_MODE_QUAD) {
cmd = 0x38;
} else if (cfg->tar_dev_cfg.io_mode == MSPI_IO_MODE_OCTAL) {
cmd = 0xe8;
} else {
cmd = 0xff;
}

if (flash_mspi_nor_mx_write_enable(flash)) {
return -EIO;
}
Expand All @@ -777,6 +798,15 @@ static int flash_mspi_nor_mx_init(const struct device *flash)
return -EIO;
}
data->timing_cfg = cfg->tar_timing_cfg;
#endif

/* if (flash_mspi_nor_mx_mem_ready(flash)) {
LOG_ERR("Flash : not ready");;
return -EIO;
}*/
LOG_DBG("Flash ready");

/* XIP will need the base address for MemoryMapped mode */

if (cfg->tar_xip_cfg.enable) {
if (mspi_xip_config(cfg->bus, &cfg->dev_id, &cfg->tar_xip_cfg)) {
Expand Down Expand Up @@ -890,19 +920,19 @@ static const struct flash_driver_api flash_mspi_nor_mx_api = {
#define MSPI_DEVICE_CONFIG_SERIAL(n) \
{ \
.ce_num = DT_INST_PROP(n, mspi_hardware_ce_num), \
.freq = 12000000, \
.io_mode = MSPI_IO_MODE_SINGLE, \
.data_rate = MSPI_DATA_RATE_SINGLE, \
.freq = DT_INST_PROP(n, mspi_max_frequency), \
.io_mode = DT_INST_STRING_UNQUOTED_OR(n, mspi_io_mode, 0), \
.data_rate = DT_INST_STRING_UNQUOTED_OR(n, mspi_data_rate, 0), \
.cpp = MSPI_CPP_MODE_0, \
.endian = MSPI_XFER_LITTLE_ENDIAN, \
.ce_polarity = MSPI_CE_ACTIVE_LOW, \
.dqs_enable = false, \
.tx_dummy = DT_INST_PROP_OR(n, rx_dummy, 8), \
.rx_dummy = DT_INST_PROP_OR(n, rx_dummy, 0), \
.tx_dummy = DT_INST_PROP_OR(n, tx_dummy, 0), \
.read_cmd = DT_INST_PROP_OR(n, read_cmd, SPI_NOR_CMD_READ_FAST), \
.write_cmd = DT_INST_PROP_OR(n, write_cmd, SPI_NOR_CMD_PP), \
.cmd_length = 1, \
.addr_length = 4, \
.addr_length = 3, \
.mem_boundary = 0, \
.time_to_break = 0, \
}
Expand Down

0 comments on commit f5a2e2f

Please sign in to comment.