- Notifications
You must be signed in to change notification settings - Fork 8.2k
Description
Describe the bug
We have a custom board with STM32G473VET6 MCU and GD25Q128EWIGR SPI flash connected to QSPI. With the upcoming Zephyr v4.3 communication with the chip stopped working properly (in terms of init process and filesystem access).
Releases v3.7 LTS, v4.2 and v4.3-rc{1,2} have been tested:
- v3.7.0 OK
- v4.2.0 OK
- v4.3.0-rc1 NOK
- v4.3.0-rc2 NOK
git bisect lead to identifying cause of behavior change to be commit b147d78 which enabled sample shifting (SSHIFT) for non-dual flash configurations.
Disabling SSHIFT fixes the issue in our case.
Working around with dummy cycles and QSPI CLK does not really solve the problem:
- setting dummy cycles for SFDP from fixed 8 to 7 does help in this case only
- setting dummy cycles for JEDEC ID reading from default 8 to 7 does not help
st,read-id-dummy-cycles = <N>;
- lowering dummy cycles for data access not tested -- default 0 dummy cycles
- changing QSPI CLK from 104 MHz to 1 MHz does not help
- SPI bus width is not set (i.e. 1-bit); tested with 4 bits too
spi-bus-width = <N>;
- all of the above tested in different mixups
- the only way communication, filesystem and filesystem tests (read/write/verify) were working again was disabling sample shifting
Regression
- This is a regression.
Steps to reproduce
- clean build the firmware (new build dir, west update)
- flash & run the firmware
- observe zephyr shell for flash_stm32_qspi and littlefs entries
- read JEDED ID with flash_read_jedec_id()
Relevant log output
## OK uart:~$ kernel reboot cold [00:00:00.000,000] <inf> flash_stm32_qspi: Reading SFDP [00:00:00.000,000] <inf> flash_stm32_qspi: qspi-nor-flash@90000000: SFDP v 1.6 AP ff with 2 PH [00:00:00.000,000] <inf> flash_stm32_qspi: PH0: ff00 rev 1.6: 16 DW @ 30 [00:00:00.000,000] <inf> flash_stm32_qspi: Reading SFDP [00:00:00.001,000] <inf> flash_stm32_qspi: qspi-nor-flash@90000000: 16 MiBy flash [00:00:00.001,000] <inf> flash_stm32_qspi: PH1: ffc8 rev 1.0: 3 DW @ 90 [00:00:00.001,000] <inf> flash_stm32_qspi: NOR quad-flash at 0x90000000 (0x1000000 bytes) [00:00:00.299,000] <inf> littlefs: littlefs partition at /lfs [00:00:00.299,000] <inf> littlefs: LittleFS version 2.11, disk version 2.1 [00:00:00.301,000] <inf> littlefs: FS at qspi-nor-flash@90000000:0x0 is 4096 0x1000-byte blocks with 512 cycle [00:00:00.301,000] <inf> littlefs: partition sizes: rd 16 ; pr 16 ; ca 64 ; la 64 [00:00:00.302,000] <inf> littlefs: Automount /lfs succeeded ## NOK uart:~$ kernel reboot cold [00:00:00.001,000] <inf> flash_stm32_qspi: Reading SFDP [00:00:00.001,000] <err> flash_stm32_qspi: SFDP magic a0888ca6 invalid [00:00:00.300,000] <inf> littlefs: littlefs partition at /lfs [00:00:00.300,000] <inf> littlefs: LittleFS version 2.11, disk version 2.1 [00:00:00.300,000] <err> littlefs: can't open flash area 0, err -19 [00:00:00.300,000] <err> fs: fs mount error (-19) [00:00:00.300,000] <err> littlefs: Automount /lfs failed: -19Impact
Functional Limitation – Some features not working as expected, but system usable.
Environment
- OS: Linux Ubuntu 24.04 LTS
- toolchain: Zephyr SDK 0.16.9 and 0.17.4
- commits tested:
- git bisect: from v3.7.1/9f824289b28d7aea2eee74f62787c385a5005453 to v4.3.0-rc2 (~13.7k commits)
- manual verification: v3.7.0, v4.2.0, v4.3.0-rc2
Additional Context
&quadspi { pinctrl-0 = <&quadspi1_clk_pa3 &quadspi1_bk1_ncs_pa2 &quadspi1_bk1_io0_pb1 &quadspi1_bk1_io1_pb0 &quadspi1_bk1_io2_pa7 &quadspi1_bk1_io3_pa6>; pinctrl-1 = <&analog_pa3 &analog_pa2 &analog_pb1 &analog_pb0 &analog_pa7 &analog_pa6>; pinctrl-names = "default", "sleep"; status = "okay"; gd25q128e: qspi-nor-flash@90000000 { compatible = "st,stm32-qspi-nor"; reg = <0x90000000>; size = <DT_SIZE_M(128)>; qspi-max-frequency = <DT_FREQ_M(104)>; label = "ext_flash"; status = "okay"; partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; storage_partition: partition@0 { label = "storage"; reg = <0x00000000 DT_SIZE_M(16)>; }; }; }; }; / { fstab { compatible = "zephyr,fstab"; lfs_cfg: lfs { compatible = "zephyr,fstab,littlefs"; mount-point = "/lfs"; partition = <&storage_partition>; read-size = <16>; prog-size = <16>; cache-size = <64>; lookahead-size = <64>; block-cycles = <512>; automount; }; }; }; Needed before v4.3:
/ { soc { quadspi: spi@a0001000 { compatible = "st,stm32-qspi"; #address-cells = <1>; #size-cells = <0>; reg = <0xa0001000 0x400>, <0x90000000 DT_SIZE_M(256)>; interrupts = <95 0>; clocks = <&rcc STM32_CLOCK_BUS_AHB3 0x00000100>; status = "disabled"; }; }; }; Disabling SSHIFT for testing, v4.3.0-rc2:
diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index e853d91d9a7..49f75d5c1df 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -1631,10 +1631,10 @@ static int flash_stm32_qspi_init(const struct device *dev) dev_data->hqspi.Init.ClockPrescaler = prescaler; /* Give a bit position from 0 to 31 to the HAL init minus 1 for the DCR1 reg */ dev_data->hqspi.Init.FlashSize = find_lsb_set(dev_cfg->flash_size) - 2; - dev_data->hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; dev_data->hqspi.Init.ChipSelectHighTime = dev_cfg->cs_high_time - 1; #if STM32_QSPI_DOUBLE_FLASH dev_data->hqspi.Init.DualFlash = QSPI_DUALFLASH_ENABLE; + dev_data->hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; /* * When the DTS has <dual-flash>, it means Dual Flash Mode Setting SFDP dummy cycles for testing, example for 7, v4.3.0-rc2:
diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index e853d91d9a7..ccf76d95347 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -495,7 +495,7 @@ static int qspi_read_sfdp(const struct device *dev, off_t addr, void *data, .Instruction = JESD216_CMD_READ_SFDP, .Address = addr, .AddressSize = QSPI_ADDRESS_24_BITS, - .DummyCycles = 8, + .DummyCycles = 7, .InstructionMode = QSPI_INSTRUCTION_1_LINE, .AddressMode = QSPI_ADDRESS_1_LINE, .DataMode = QSPI_DATA_1_LINE, Output for SFDP reading with 7 dummy cycles:
[00:00:00.001,000] <inf> flash_stm32_qspi: Reading SFDP [00:00:00.001,000] <inf> flash_stm32_qspi: qspi-nor-flash@90000000: SFDP v 1.6 AP ff with 2 PH [00:00:00.001,000] <inf> flash_stm32_qspi: PH0: ff00 rev 1.6: 16 DW @ 30 [00:00:00.001,000] <inf> flash_stm32_qspi: Reading SFDP [00:00:00.001,000] <inf> flash_stm32_qspi: qspi-nor-flash@90000000: 16 MiBy flash [00:00:00.001,000] <inf> flash_stm32_qspi: PH1: ffc8 rev 1.0: 3 DW @ 90 [00:00:00.001,000] <inf> flash_stm32_qspi: NOR quad-flash at 0x90000000 (0x1000000 bytes) [00:00:00.300,000] <inf> littlefs: littlefs partition at /lfs [00:00:00.300,000] <inf> littlefs: LittleFS version 2.11, disk version 2.1 [00:00:00.302,000] <inf> littlefs: FS at qspi-nor-flash@90000000:0x0 is 4096 0x1000-byte blocks with 512 cycle [00:00:00.302,000] <inf> littlefs: partition sizes: rd 16 ; pr 16 ; ca 64 ; la 64 [00:00:00.302,000] <err> littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1386: Corrupted dir pair at {0x1, 0x0} [00:00:00.302,000] <wrn> littlefs: can't mount (LFS -84); formatting [00:00:00.302,000] <wrn> littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:2109: Superblock 0x0 has become unwritable [00:00:00.302,000] <err> littlefs: format failed (LFS -28) [00:00:00.302,000] <err> fs: fs mount error (-28) [00:00:00.302,000] <err> littlefs: Automount /lfs failed: -28 Making sure flash is erased and rebooting in case SFDP looks ok:
uart:~$ flash erase ext_flash 0 1000000 uart:~$ flash erase qspi-nor-flash@90000000 0 1000000 uart:~$ flash read qspi-nor-flash@90000000 0 128 00000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000000A0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000000B0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000000C0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000000D0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000000E0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000000F0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000110: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00000120: ff ff ff ff ff ff ff ff |........ | uart:~$ flash read qspi-nor-flash@90000000 1000 128 00001000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000010A0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000010B0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000010C0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000010D0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000010E0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 000010F0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001110: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |........ ........| 00001120: ff ff ff ff ff ff ff ff |........ | uart:~ kernel reboot cold JEDEC ID testing:
// CONFIG_FLASH_JESD216_API=y const struct device *flash_dev = device_get_binding("ext_flash"); uint8_t jedec_id[3]; int ret = flash_read_jedec_id(flash_dev, jedec_id); if (ret == 0) { // expected 18 C8 40 }