Skip to content
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

Add support Flash QSPI on S32Z270 #78073

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

congnguyenhuu
Copy link
Contributor

@congnguyenhuu congnguyenhuu commented Sep 6, 2024

Introduce support HyperFlash memory devices on a NXP S32 QSPI bus. This driver uses a fixed LUT configuration that defined in HAL RTD HyperFlash driver and allows to read, write, and erase HyperFlash devices.
Add support QSPI secure flash protection (SFP) for memory control NXP S32 QSPI.
Enable support Flash QSPI on S32Z2XX, the on-board S26HS512T 512M-bit HyperFlash memory is connected to the QSPI controller port A1. This board configuration selects it as the default flash controller.

The test result:

west twister  --disable-warnings-as-errors --device-testing --device-serial=/dev/ttyUSB0 -v --runtime-artifact-cleanup --west-runner trace32 --west-flash="--config=./config.t32" -p s32z2xxdc2/s32z270/rtu1  -T samples/subsys/fs/littlefs -T samples/subsys/settings -T samples/subsys/shell/fs -T tests/drivers/flash -T tests/subsys/fs -T tests/subsys/settings -T tests/subsys/storage/flash_map -T tests/subsys/logging/log_backend_fs
INFO    - Using Ninja..
INFO    - Zephyr version: 8c53d91026a8
INFO    - Using 'zephyr' toolchain.
INFO    - Building initial testsuite list...

Device testing on:

| Platform                | ID   | Serial device   |
|-------------------------|------|-----------------|
| s32z2xxdc2/s32z270/rtu1 |      | /dev/ttyUSB0 |

INFO    - JOBS: 6
INFO    - Adding tasks to the queue...
INFO    - Added initial list of jobs to queue
INFO    - 58/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/storage/flash_map/storage.flash_map   PASSED (device 80.480s)
INFO    - 59/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/logging/log_backend_fs/logging.backend.fs.automounted PASSED (device 38.796s)
INFO    - 60/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/settings/functional/file/settings.file PASSED (device 28.017s)
INFO    - 61/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/logging/log_backend_fs/logging.backend.fs.manualmounted PASSED (device 40.086s)
INFO    - 62/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/settings/functional/nvs/settings.functional.nvs.chosen PASSED (device 27.685s)
INFO    - 63/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/settings/functional/fcb/settings.functional.fcb.chosen PASSED (device 27.686s)
INFO    - 64/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/settings/functional/fcb/settings.functional.fcb PASSED (device 27.692s)
INFO    - 65/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/settings/functional/nvs/settings.functional.nvs.dk PASSED (device 27.624s)
INFO    - 66/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/settings/functional/nvs/settings.functional.nvs PASSED (device 27.641s)
INFO    - 67/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/fs/fat_fs_api/filesystem.fat.api.sdmmc SKIPPED (runtime filter)
INFO    - 68/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/fs/fat_fs_api/filesystem.fat.api.mmc  SKIPPED (runtime filter)
INFO    - 69/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/storage/flash_map/storage.flash_map.mbedtls PASSED (device 80.335s)
INFO    - 70/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/storage/flash_map/storage.flash_map.psa PASSED (device 80.570s)
INFO    - 71/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/fs/fcb/filesystem.fcb                 PASSED (device 40.218s)
INFO    - 72/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/settings/file/settings.file.raw       PASSED (device 30.420s)
INFO    - 73/77 s32z2xxdc2/s32z270/rtu1   samples/subsys/settings/sample.subsys.settings     PASSED (device 27.357s)
INFO    - 74/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/fs/fs_api/filesystem.api              PASSED (device 26.865s)
INFO    - 75/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/settings/fcb/settings.fcb.raw         PASSED (device 47.201s)
INFO    - 76/77 s32z2xxdc2/s32z270/rtu1   tests/drivers/flash/common/drivers.flash.common.default PASSED (device 26.663s)
INFO    - 77/77 s32z2xxdc2/s32z270/rtu1   tests/subsys/fs/littlefs/filesystem.littlefs.default PASSED (device 39.218s)

INFO    - 77 test scenarios (77 test instances) selected, 59 configurations skipped (57 by static filter, 2 at runtime).
INFO    - 18 of 77 test configurations passed (100.00%), 0 failed, 0 errored, 59 skipped with 0 warnings in 808.67 seconds
INFO    - In total 134 test cases were executed, 355 skipped on 1 out of total 4 platforms (25.00%)
INFO    - 18 test configurations executed on platforms, 0 test configurations were only built.

@zephyrbot
Copy link
Collaborator

zephyrbot commented Sep 6, 2024

The following west manifest projects have been modified in this Pull Request:

Name Old Revision New Revision Diff
hal_nxp zephyrproject-rtos/hal_nxp@683c007 zephyrproject-rtos/hal_nxp#434 zephyrproject-rtos/hal_nxp#434/files

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@zephyrbot zephyrbot added manifest manifest-hal_nxp DNM This PR should not be merged (Do Not Merge) labels Sep 6, 2024
@congnguyenhuu congnguyenhuu changed the title Add support flash qspi on S32Z270 Add support Flash QSPI on S32Z270 Sep 6, 2024
@Laczen Laczen removed their request for review September 6, 2024 11:05
dts/bindings/mtd/nxp,s32-qspi-hyperflash.yaml Outdated Show resolved Hide resolved
drivers/flash/flash_nxp_s32_qspi_hyperflash.c Outdated Show resolved Hide resolved
boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_pinctrl.dtsi Outdated Show resolved Hide resolved
@Dat-NguyenDuy Dat-NguyenDuy requested review from gmarull and removed request for gmarull October 7, 2024 01:20
@manuargue manuargue added this to the v4.0.0 milestone Oct 9, 2024
manuargue
manuargue previously approved these changes Oct 9, 2024
Copy link
Member

@manuargue manuargue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reapproving, my comments addressed

@gmarull gmarull dismissed their stale review October 9, 2024 15:25

looks better than before, so will let others finish the review.

@congnguyenhuu
Copy link
Contributor Author

congnguyenhuu commented Oct 12, 2024

I have rebased to fix conflict the west manifest. Could you please revisit PR? @nordicjm @manuargue @Dat-NguyenDuy
And there is a new update:
drivers: memc_nxp_s32_qspi: change DT_REG_ADDR to DT_REG_ADDR_RAW
Following the commit f98fde0, DT_REG_ADDR now expands with a 'U'
suffix as an unsigned value. However, for compatibility with IS_EQ,
a raw value without any suffix is required. Therefore, this update is
necessary.

@congnguyenhuu
Copy link
Contributor Author

Hello @de-nordic, could you visit this PR? thanks.

Dat-NguyenDuy
Dat-NguyenDuy previously approved these changes Oct 13, 2024
Comment on lines 14 to 24
start-address:
type: int
required: true
description: |
Specifies the specific flash memory region start address.
end-address:
type: int
required: true
description: |
Specifies the specific flash memory region end address.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this not using reg?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a problem prevent me, the QSPI node has multiple child nodes with different compatible bindings (device flash nodes). In some cases, they all use reg but it is possible dupliacte, which triggers a duplicate reg warning. To avoid this, I decided to use the reg property only for the device flash node.
Do you have any suggestions on how to handle this?@nordicjm

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what you mean? You can have a reg inside of a reg, that's how flash partitions work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use-case:

&qspi0 {
	sfp_frad_0: sfp_frad@0 {
		compatible = "nxp,s32-qspi-sfp-frad";
		reg = <0x0 DT_SIZE_M(512)>;
	};

	s26hs512t: s26hs512t@0 {
		compatible = "nxp,s32-qspi-hyperflash";
		reg = <0>;
		status = "okay";

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			storage_partition: partition@0 {
				label = "storage";
				reg = <0x0 0x10000>;
			};
		};
	};

the log warning:
image

Copy link
Contributor Author

@congnguyenhuu congnguyenhuu Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found solution for this, I updated to move sfp_frad_0 into a parent node, look like as:

&qspi0 {
	sfp {
		compatible = "secure-flash-protection";
		#address-cells = <1>;
		#size-cells = <1>;

	        frad_0: frad@0 {
		        compatible = "nxp,s32-qspi-sfp-frad";
		        reg = <0x0 DT_SIZE_M(512)>;
	        };
        };

	s26hs512t: s26hs512t@0 {
		compatible = "nxp,s32-qspi-hyperflash";
		reg = <0>;
		status = "okay";

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			storage_partition: partition@0 {
				label = "storage";
				reg = <0x0 0x10000>;
			};
		};
	};

dts/bindings/qspi/nxp,s32-qspi-sfp-frad.yaml Show resolved Hide resolved
dts/bindings/qspi/nxp,s32-qspi-sfp-mdad.yaml Show resolved Hide resolved
Comment on lines 24 to 22
program-page-size:
type: int
required: true
description: |
The programming page size of the flash memory device,
as specified in the flash memory device datasheet.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can this not use write-block-size which already exists?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this property differs with write-block-size, this defines maximum of programming page buffer size configuration for hardware device flash. To avoid confusing I renamed this property to max-program-buffer-size.
As specified configuration in the flash memory device datasheet.
image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the write block size set then, that is required for flash, and erase block size?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write block size being a define in code is useless and wrong, there is a dts property, likewise erase block size should be in dts, it's a hardware property (the page size is different, that is what size you want to erase, it is not the erase size)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that write-block-size and erase-block-size, defined in https://github.com/zephyrproject-rtos/zephyr/blob/main/dts/bindings/mtd/soc-nv-flash.yaml which uses for internal flash.
I refer the other support external flash, I see most them not use these property.
eg. a supported driver that not use these. the write block size is fixed.
https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/flash/nrf_qspi_nor.c#L1172

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @nordicjm, I’ve addressed all your comments. Could you please revisit the PR? I hope you happy with this and can approve my changes so we can merge it soon. Thanks.

@@ -344,6 +344,7 @@
readoc = "1-4-4";
writeoc = "1-4-4";
has-32k-erase;
program-page-size = <256>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and to go with the above comment, this would not be 256, unless you mean you can't write anything less than 256 bytes, e.g. 4 byte write would fail, which I doubt is the case

Copy link
Contributor Author

@congnguyenhuu congnguyenhuu Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls see my above comments #78073 (comment)

@congnguyenhuu congnguyenhuu force-pushed the nxp-s32ze-support-flash-qspi branch 3 times, most recently from 202af1f to 29a5fdd Compare October 21, 2024 02:11
#include "jesd216.h"

#define QSPI_ERASE_VALUE 0xff
#define QSPI_WRITE_BLOCK_SIZE 1U
Copy link
Collaborator

@nordicjm nordicjm Oct 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to come from dts (the write block size). Does your driver switch the commands it sends depending upon what some uses? E.g. if I use flash_write() with 129 bytes it will send 32 commands to write 4 bytes followed by 1 command to write 1 byte or will it just fail at the last part? Likewise what if there is a flash memory used with this that does not support 1 byte writes and is configures for 4 byte writes only? As an aside, without the coming from dts with the correct name, things like MCUboot will assume default values that, like in the example above, could be wrong

Copy link
Contributor Author

@congnguyenhuu congnguyenhuu Oct 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This driver will use memory-alignment dt properties (https://github.com/zephyrproject-rtos/zephyr/blob/main/dts/bindings/mtd/nxp%2Cs32-qspi-device.yaml#L17) to pad (by adding 0xFF) at the unaligned data parts. E.g with memory-alignment=2 use flash_write() with 129 bytes it will send 130 bytes (last byte is padded if offset is even number). From application pov, flash_write() can be used with any size between 1 and the value specified in max-program-buffer-size dt properties.
This platform does not support MCUboot now so I'm not sure this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that is wrong? That's fine if you are using a flash chip, but you get non-flash SPI/QSPI devices (e.g. FRAM) and writing 0xff will write 0xff over data you do not want to touch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This driver supports hyperflash chip (using s26hs512 flash chip on board), writing 0xff not affect the existed data.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

People that will write code for subsystem to work on any device have to align offset and size to write-block-size anyway, so by not requiring that. So if somebody delivers something for your device with assumption that data will be padded, will have to fix that when testing code against other device.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@de-nordic @nordicjm i believe your concern for this topic has been addressed (by updating the PR to use write-block-size), could both of you help me to take another look.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@de-nordic @nordicjm i believe your concern for this topic has been addressed (by updating the PR to use write-block-size), could both of you help me to take another look.

You have added a write block size of 1, so does that mean then when I call this function, your driver writes exactly one byte with no padding or 0xff's what so ever?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are saying this write block size. this is write block size for a serial NOR flash device. it allows to write exactly 1 byte without padding.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mean for a serial NOR flash device, I mean the actual command that comes out the chip, does it send a command to the other device consisting of writing 1 byte and 1 byte only without any padding or 0xff's or does it send a command with additional data/padding?

Following the commit f98fde0, DT_REG_ADDR now expands with a 'U'
suffix as an unsigned value. However, for compatibility with IS_EQ,
a raw value without any suffix is required. Therefore, this update is
necessary.

Signed-off-by: Cong Nguyen Huu <[email protected]>
Add support QSPI secure flash protection (SFP)

Signed-off-by: Cong Nguyen Huu <[email protected]>
Create common source code to use for supporting HyperFlash.

Rename 'FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME' to
'FLASH_NXP_S32_QSPI_SFDP_RUNTIME' as a common kconfig.

Update to use 'program-page-size' instead of using
'CONFIG_FLASH_NXP_S32_QSPI_LAYOUT_PAGE_SIZE' for setting
memory pageSize because this is the page size to write flash,
is not the erase sector size.

Signed-off-by: Cong Nguyen Huu <[email protected]>
Add support HyperFlash memory devices on a NXP S32 QSPI bus.
This driver uses a fixed LUT configuration that defined in HAL RTD
HyperFlash driver.
Driver allows to read, write and erase HyperFlash devices.

Signed-off-by: Cong Nguyen Huu <[email protected]>
The on-board S26HS512T 512M-bit HyperFlash memory is connected to
the QSPI controller port A1.
This board configuration selects it as the default flash controller.

Signed-off-by: Cong Nguyen Huu <[email protected]>
Enable flash samples for s32z board

Signed-off-by: Cong Nguyen Huu <[email protected]>
Enable flash tests for s32z board

Signed-off-by: Cong Nguyen Huu <[email protected]>
@congnguyenhuu
Copy link
Contributor Author

Hello @nordicjm, after some consideration, I added the write-block-size property to the DTS. I noticed it relates to the existing memory-alignment property. Therefore, I decided to remove memory-alignment and can use write-block-size instead to calculate padding for unaligned accesses.

Memory alignment in bytes, used to calculate padding when performing
unaligned accesses.
If not provided, 1 byte alignment will be selected.
The number of bytes used in write operations, it also used to calculate padding when
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still mentioning padding.

{
Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev);

return ((offset >= 0) && (offset < memory_cfg->memSize) &&
Copy link
Collaborator

@de-nordic de-nordic Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if size and offset get large enough you can get into situation where they overflow and you and up having true in line 22, even though parameters are out of range.
More proper would be to do:

return (offset >= 0 && offset < memory_cfg->memSize && ((memory_cfg->mem_size - offset) >= size)

}

if (!area_is_subregion(dev, offset, size)) {
return -ENODEV;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am quite sure other drivers return -EINVAL here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no check of offset nor size for alignment to write-block-size set in DTS, I know that device permits 1, but if you set it to something else and let to be ignored, this will allow different subsystems write/read with different alignment and produce data that they may not be able mutually read from the same device.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: File System area: Flash area: Logging area: MEMC area: Samples Samples area: Settings Settings subsystem area: Shell Shell subsystem area: Storage Storage subsystem DNM This PR should not be merged (Do Not Merge) manifest manifest-hal_nxp platform: NXP S32 NXP Semiconductors, S32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants