-
Notifications
You must be signed in to change notification settings - Fork 7.4k
add spi nand driver #50690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
add spi nand driver #50690
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this contribution.
Some clean up required.
My main request would be to remove STM32 mentions, since there is nothing STM32 specific here aside from the board used for test.
@rogeryou can you please format your commits as described here: |
9755c14
to
901b863
Compare
I have formated my commits. |
@rogeryou, thank you for this contribution. It would be very nice to have nand flash support in zephyr. Regarding the PR, I have seen that the ecc is hidden for the user as to be able to use the standard flash interface. This is a good thing, but doesn't this also make any other part of the oob data unavailable ? IMHO it would be good to extend the flash driver for nand flashes with read/write possibilities of the oob data. This would allow adding bad block info to the oob area. |
@rogeryou |
Thank you for your suggestion. We will add APIs that operate OOB later. |
Could you tell me which part of the program you mentioned? |
66a06e6
to
9d94e4c
Compare
Hi @de-nordic , we have fixed the compliance and documentation, please review again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be configuration for existing flash tests added, as the driver implements the Flash API and should work with these tests and samples we already have.
Some comments left, still reviewing.
@@ -63,6 +63,8 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_SMARTBOND flash_smartbond.c) | |||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_TELINK_B91 soc_flash_b91.c) | |||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_XMC4XXX soc_flash_xmc4xxx.c) | |||
zephyr_library_sources_ifdef(CONFIG_SPI_FLASH_AT45 spi_flash_at45.c) | |||
zephyr_library_sources_ifdef(CONFIG_SPI_NAND bch.c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not to be fixed with this PR, but just want to mention that I will propose enhancement where bch implementation gets moved to CRC subsystem.
drivers/flash/Kconfig.nand
Outdated
@@ -0,0 +1,38 @@ | |||
# Copyright (c) 2022 Macronix International Co., Ltd. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably want to update date in copyrights.
drivers/flash/Kconfig.nand
Outdated
Device is connected to SPI bus, it has to | ||
be initialized after SPI driver. | ||
|
||
config SPI_NAND_CS_WAIT_DELAY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be defined in DTS for a device?
drivers/flash/Kconfig.nand
Outdated
help | ||
This is the wait delay (in us) to allow for CS switching to take effect | ||
|
||
config SPI_NAND_IDLE_IN_DPD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be defined in dts?
drivers/flash/spi_nand.c
Outdated
LOG_ERR("Enable continuous read failed: %d\n", secur_reg); | ||
} | ||
|
||
out: release_device(dev); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Labels alone in the line, drop the function call to the next line.
drivers/flash/spi_nand.c
Outdated
return ret; | ||
} | ||
|
||
static int spi_nand_conti_read_enable(const struct device *dev) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we merge the spi_nand_conti_read_enable
and spi_nand_conti_read_disable
. They are looking very similar.
drivers/flash/spi_nand.c
Outdated
size -= chunk; | ||
} | ||
|
||
out: release_device(dev); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Labels get own lines.
drivers/flash/spi_nand.c
Outdated
offset = addr % data->page_size; | ||
chunk = (offset + size < data->page_size) ? | ||
size : (data->page_size - offset); | ||
read_bytes = chunk; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need read_bytes
; it seem that is equivalent of chunk
, through the loop, and not used outside.
samples/drivers/spi_nand/README.rst
Outdated
:name: JEDEC SPI-NAND flash | ||
:relevant-api: flash_interface | ||
|
||
Use the flash API to interact with an SPI NOR serial flash memory device. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the flash API to interact with an SPI NOR serial flash memory device. | |
Use the flash API to interact with an SPI NAND serial flash memory device. |
9d94e4c
to
e43cdde
Compare
e43cdde
to
04e8854
Compare
Hi @de-nordic @embed , since Zephyr has supported Multi-bit SPI bus last year, do we need to rework this PR based on MSPI (drivers/mspi.h) instead of SPI (drivers/spi.h)? Many controller IP core such as FlexSPI, stm32-ospi, cadence-xSPI or Renesas-xSPI support QSPI NAND Flash. |
@daniel-0723 I follow the philosophy of first make it work. How much effort is it to finish this as a proper SPI driver and then have another PR for adding MSPI support? I would vote for meeting the original PR goal, that is a working generic SPI-NAND driver. CC: @de-nordic On another note, I can't reply to your comment for some reason so I made a new comment. |
drivers/flash/spi_nand.h
Outdated
#define SPI_NAND_CMD_ECC_STAT_READ 0x7C | ||
|
||
/* Page, sector, and block size are standard, not configurable. */ | ||
#define SPI_NAND_PAGE_SIZE 2048 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Page and block sizes should either come from device tree, or better from ONFI table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for leveraging the ONFI table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
04e8854
to
0c4ca12
Compare
bce4642
to
6077f25
Compare
drivers/flash/spi_nand.h
Outdated
|
||
/* Status register bits */ | ||
#define SPI_NAND_WIP_BIT BIT(0) /* Write in progress */ | ||
#define SPI_NAND_WEL_BIT BIT(1) /* Write enable latch */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused, remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
drivers/flash/spi_nand.h
Outdated
/* Status Register Bits 0xC0 */ | ||
#define SPINAND_STATUS_BIT_WIP 0x1 /* Write In Progress */ | ||
#define SPINAND_STATUS_BIT_WEL 0x2 /* Write Enable Latch */ | ||
#define SPINAND_STATUS_BIT_ERASE_FAIL 0x4 /* Erase failed */ | ||
#define SPINAND_STATUS_BIT_PROGRAM_FAIL 0x8 /* Program failed */ | ||
#define SPINAND_STATUS_BIT_ECC_STATUS_MASK 0x30 /* ECC status */ | ||
#define SPINAND_STATUS_ECC_STATUS_NO_ERR 0x00 | ||
#define SPINAND_STATUS_ECC_STATUS_ERR_COR 0x10 | ||
#define SPINAND_STATUS_ECC_STATUS_ERR_NO_COR 0x20 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused, remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
drivers/flash/spi_nand.h
Outdated
#define SPINAND_SECURE_BIT_CONT 0x04 /* continuous read enable */ | ||
#define SPINAND_SECURE_BIT_ECC_EN 0x10 /* On-die ECC enable */ | ||
#define SPINAND_SECURE_BIT_OTP_EN 0x40 | ||
#define SPINAND_SECURE_BIT_OTP_PROT 0x80 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused, remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
drivers/flash/spi_nand.h
Outdated
#define SPINAND_STATUS_ECC_STATUS_ERR_NO_COR 0x20 | ||
|
||
/* Secure OTP Register Bits 0xB0 */ | ||
#define SPINAND_SECURE_BIT_QE 0x01 /* Quad enable */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused, remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
drivers/flash/spi_nand.h
Outdated
#define SPINAND_BLOCK_PROT_BIT_SP 0x01 | ||
#define SPINAND_BLOCK_PROT_BIT_COMPLE 0x02 | ||
#define SPINAND_BLOCK_PROT_BIT_INVERT 0x04 | ||
#define SPINAND_BLOCK_PROT_BIT_BP0 0x08 | ||
#define SPINAND_BLOCK_PROT_BIT_BP1 0x10 | ||
#define SPINAND_BLOCK_PROT_BIT_BP2 0x20 | ||
#define SPINAND_BLOCK_PROT_BIT_BPRWD 0x80 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused, remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
drivers/flash/spi_nand.c
Outdated
} | ||
|
||
/* size must be a multiple of sub-page */ | ||
if ((size % driver_cfg->sub_page_size) != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size
can still be bigger then the device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
while (size > 0) { | ||
|
||
/* Don't write more than a page. */ | ||
offset = addr % data->page_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that page_size
may be bigger than sub_page_size
, in which case this alignment in this line may lead to offset pointing to whole page before offset of sub_page_size
, that has been accepted by line 534.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
if ((size % data->block_size) != 0) { | ||
return -EINVAL; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No check for addr
being positive and size + addr
to fit into real device size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
drivers/flash/spi_nand.c
Outdated
|
||
/* verify that eccbytes has the expected value */ | ||
if (data->nbc.bch->ecc_words * 4 != eccbytes) { | ||
LOG_ERR("invalid eccbytes %u, should be %u\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this print hex rather than decimal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
drivers/flash/spi_nand.c
Outdated
|
||
data->page_buf = (uint8_t *)k_malloc(data->page_size + data->oob_size); | ||
if (data->page_buf == NULL) { | ||
LOG_ERR("Not enougn heap\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why pass-through? Shouldn't that just fail the entire operation already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sloved
1ef8ab7
to
7ae596a
Compare
Add SPI NAND Flash driver support Signed-off-by: Daniel Zhang <danielzhang@mxic.com.cn>
555fd5d
to
eaf79f9
Compare
|
return &flash_nand_parameters; | ||
} | ||
|
||
static const struct flash_driver_api spi_nand_api = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Driver API needs to be wrapped in macro.
static const struct flash_driver_api spi_nand_api = { | |
static DEVICE_API(flash, spi_nand_api) = { |
DEVICE_DT_INST_DEFINE(0, &spi_nand_init, NULL, | ||
&spi_nand_data_0, &spi_nand_config_0, | ||
POST_KERNEL, CONFIG_SPI_NAND_INIT_PRIORITY, | ||
&spi_nand_api); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it would be possible to have multiple instances use, DT_INST_FOREACH_STATUS_OKAY
required: true | ||
type: int | ||
description: | | ||
Size (in bytes) of the Flash memory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a trailing newline to the file.
@@ -0,0 +1,3 @@ | |||
CONFIG_STDOUT_CONSOLE=y | |||
CONFIG_FLASH=y | |||
CONFIG_HEAP_MEM_POOL_SIZE=100000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing trailing newline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want driver specific samples? Can't you re-use the existing flash driver sample?
LOG_ERR("get feature failed: %d", ret); | ||
goto out; | ||
} | ||
if (!(secur_reg & SPINAND_SECURE_BIT_CONT)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!(secur_reg & SPINAND_SECURE_BIT_CONT)) { | |
if ((secur_reg & SPINAND_SECURE_BIT_CONT) == 0U) { |
LOG_ERR("get feature failed: %d", ret); | ||
goto out0; | ||
} | ||
if (!(secur_reg & SPINAND_SECURE_BIT_OTP_EN)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!(secur_reg & SPINAND_SECURE_BIT_OTP_EN)) { | |
if ((secur_reg & SPINAND_SECURE_BIT_OTP_EN) == 0U) { |
release_device(dev); | ||
} | ||
|
||
if (onfi_table[ONFI_CONT_READ_168] & 0x02) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a define for the 0x02
constant?
if (onfi_table[ONFI_CONT_READ_168] & 0x02) { | |
if ((onfi_table[ONFI_CONT_READ_168] & 0x02) != 0U) { |
goto out1; | ||
} | ||
|
||
if (secur_reg & SPINAND_SECURE_BIT_OTP_EN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (secur_reg & SPINAND_SECURE_BIT_OTP_EN) { | |
if ((secur_reg & SPINAND_SECURE_BIT_OTP_EN) != 0U) { |
goto out; | ||
} | ||
/* Only clear if GET_FEATURE worked and something's set. */ | ||
if (reg & SPINAND_BLOCK_PROT_BIT_BP_MASK) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (reg & SPINAND_BLOCK_PROT_BIT_BP_MASK) { | |
if ((reg & SPINAND_BLOCK_PROT_BIT_BP_MASK) != 0U) { |
This PR is updated for #43915.
Add SPI NAND block device driver for using SPI NAND Flash like Macronix Flash MX31LF4GE4BC.
This driver is tested on STM32L562E-DK.
The license of BCH code is updated.