-
Notifications
You must be signed in to change notification settings - Fork 8k
Add QSPI NOR flash driver for SF32LB #96085
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?
Conversation
ce5be5e
to
7335cff
Compare
7335cff
to
9c0f2b4
Compare
9c0f2b4
to
488686a
Compare
5218a60
to
003a034
Compare
Questions for @rabbitsaviola
|
it's ok that DMA code is not placed in RAM as sequence command mode used.
write doesn't work when chunk_len > FIFO size is because RBSIZE is set to 3 by L535. If RBSIZE is 0, chunk_len=128byte works well. |
last push: dropped row boundary config as it's not needed |
|
||
chosen { | ||
zephyr,flash = &py25q128ha; | ||
zephyr,flash = &nor; |
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.
zephyr,flash
chosen is usually a node with nv-soc-flash
compatible, and it is what's expected by several DT macros and MCUboot.
COND_CODE_1(DT_NODE_HAS_COMPAT(DT_GPARENT(node_id), soc_nv_flash), (DT_GPARENT(node_id)), \ |
Line 144 in 4b3cb73
dt_prop(write_block_size PATH "${flash_node}" PROPERTY "write-block-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.
This soc has no "nv-soc-flash", it can only XIP from an external QSPI NOR. We may have to adjust these macros/cmake utils when needed I guess.
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.
The difficulty here is keeping the QSPI NOR description aligned with what one would find in Linux (I think it is, except for the extra binding I had to create due to QSPI controllers not owning a proper device class) and making Zephyr happy at the same time if we use that same QSPI NOR for XIP. I'm open to better suggestions, but I think it's yet another case of Zephyr going on its own, making things just difficult.
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 can have a look at
ext_flash_ctrl: qspi-flash-controller@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.
You can have a look at
ext_flash_ctrl: qspi-flash-controller@0 { for an example of how this should be done in my opinion to work properly with what Zephyr MCUboot and DT Macros except.
IMHO this is not a good devicetree description. You have 3 levels just to make Zephyr happy (quadspi, ext_flash_ctrl and then ext_flash). I doubt you would find this in parts with such capability in Linux (like ST MP1/2)
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 doubt you would find this in parts with such capability in Linux (like ST MP1/2)
Yes, Linux is simpler indeed
https://github.com/STMicroelectronics/linux/blob/f01241fbba4d879fa770685629b49d42e904e43c/arch/arm/boot/dts/st/stm32h750i-art-pi.dts#L188
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 doubt you would find this in parts with such capability in Linux (like ST MP1/2)
Yes, Linux is simpler indeed https://github.com/STMicroelectronics/linux/blob/f01241fbba4d879fa770685629b49d42e904e43c/arch/arm/boot/dts/st/stm32h750i-art-pi.dts#L188
The problem in Zephyr is that QSPI controllers have no proper driver class, so we currently have 1) a mess in drivers/flash and 2) devicetree zephyrisms to make things "work". To keep the controller/flash aligned with what one usually finds in Linux, I had to create the extra "memory" type node where you specify the memory-mapped absolute address.
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 had to create the extra "memory" type node where you specify the memory-mapped absolute address.
You can probably use ranges
for that as suggested here
#97413 (comment)
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 had to create the extra "memory" type node where you specify the memory-mapped absolute address.
You can probably use
ranges
for that as suggested here #97413 (comment)
will give it a shot, thanks for the suggestion
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.
ranges
does not work as expected because
config FLASH_BASE_ADDRESS
hex "Flash Base Address"
default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) if (XIP && (ARM || ARM64)) || !ARM
And since the flash@0
parent node has #size-cells set to 0, range translation will not happen, keeping FLASH_BASE_ADDRESS
set to 0. Instead, I've now changed the flash base address in the SoC defconfig, so it points to the memory-mapped address. This way we keep aligned with Linux (where the '0' means SPI slave 0, as it's a child of an SPI bus) and we can skip devicetree zephyrisms.
static const struct flash_sf32lb_mpi_qspi_nor_config config##n = { \ | ||
.params = \ | ||
{ \ | ||
.write_block_size = 4U, \ |
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.
Should be set in flash device node via nv-soc-flash
compatible's write-block-size
property.
Related discussion #95152 (comment)
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.
As mentioned above, this is already known because we always execute from a QSPI NOR (not an internal NV flash where these values may differ depending on SoC)
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.
But the driver can be used with different NOR chips, isn't write-block-size a NOR chip property?
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 think it should actually be set to 1 (as in spi_nor.c driver, which deals with jedec compliant devices), are there any SPI NORs requiring something else?
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 think it should actually be set to 1
Ok, but let's set it via DT instead of hardcoding it in the driver.
are there any SPI NORs requiring something else?
I can't say
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 think it should actually be set to 1
Ok, but let's set it via DT instead of hardcoding it in the driver.
I don't think this is a variable attribute in JEDEC compliant SPI NORs (as you can see as well in spi_nor.c), it could actually be made a driver-level static variable.
.params = \ | ||
{ \ | ||
.write_block_size = 4U, \ | ||
.erase_value = 0xFFU, \ |
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.
Ditto, with erase-block-size
Related discussion #96443 (comment)
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.
On SPI NOR devices, erase size is not strictly fixed, you can erase per sector, block or entire chip.
ba3f8e5
to
f8292de
Compare
last push: moved flash nor parameters to module-level variable, same as in |
178403c
to
8274aca
Compare
Add compatible for SiFli SF32LB MPI operating as QSPI NOR controller. Signed-off-by: Gerard Marull-Paretas <[email protected]>
Compatible should be set at board level, depending on how MPI IP is used (e.g. NOR, NAND, PSRAM). Signed-off-by: Gerard Marull-Paretas <[email protected]>
No longer used. Signed-off-by: Gerard Marull-Paretas <[email protected]>
Ideally we should be able to just use jedec,spi-nor (to keep Linux compatibility), but, QSPI controllers live in a limbo in Zephyr. Adding this binding won't make things worse than they are. Signed-off-by: Gerard Marull-Paretas <[email protected]>
Command was missing. Signed-off-by: Gerard Marull-Paretas <[email protected]>
So we can obtain a register address (as hex) given its name. Signed-off-by: Gerard Marull-Paretas <[email protected]>
Take it from the chosen flash node parent (MPI controller) 'nor' register, which contains the memory mapped address for the NOR flash. Signed-off-by: Gerard Marull-Paretas <[email protected]>
Initial driver for the SF32LB MPI accessing QSPI NOR flash devices. Signed-off-by: Gerard Marull-Paretas <[email protected]>
So that flash driver can be used (MPI2 works in QSPI mode). Signed-off-by: Gerard Marull-Paretas <[email protected]>
Allow obtaining SFDP parameters using SF32LB driver. Signed-off-by: Gerard Marull-Paretas <[email protected]>
8274aca
to
e601bd6
Compare
|
Add flash (QSPI NOR) driver for SF32LB