cancel
Showing results for 
Search instead for 
Did you mean: 

Nor Flash

huangk
New Contributor II

hi ,

I have a project recently, it uses the NOR flash S25FL512SAGMFIG11  on the board, the processor is Xilinx Zynqmp SOC, arm64.  the linux kernel is 4.19, the code base is Xilinx 2019.2.     ----Linux version 4.19.0-xilinx-v2019.2------

As blew picture of schematic  of  how we use it on the board.

After I bring up the board, I can work with the board for about 3 month, I use the NOR flash store the boot images and program files,

I have erase/write this NOR about 1000+ times, some times I leave it run overnight to repeat read/write from/to the flash.

The problem is,  last week, after I write about 18MB data into the flash, I can not write it again any more, but read from it has no problem.

I guess the problem is caused by the system reset action, I do the system reset(reboot from linux) to the board after I successfully program the ~18MB data into the flash. And again, I do the same action a lot of times before the issue, I did not power cycle the board after programming the data, I just reboot it from the linux.

Now, I still can read it from u-boot and linux, but can not erase/write it from u-boot/linux, it all seems like the whole flash block is locked, I do not know how to un-lock it.

the error reported from u-boot is like below:

ZynqMP> sf write 0x200000 0x3000000 1
device 0 offset 0x3000000, size 0x1
SF: Timeout!
SF: 1 bytes @ 0x3000000 Written: ERROR -110

 

the error reported from linux is like:

Erasing blocks: 0/72 (0%)
Erasing blocks: 1/72 (1%)
While erasing blocks 0x00000000-0x00040000 on /dev/mtd2: Input/output error
Fail to burn data file into flash

any idea of this issue? do you think the flash is damaged and can not recovered? 

 

the schematic:

Image 420.jpg

 

0 Likes
1 Solution
TakahiroK_16
Employee

Hello,

 

I reviewed the timeline of the 'linux-xlnx' source tree and found:

1. In xilinx-v2020.1, 'm25p80.c' is removed and its content is moved to 'spi-nor.c'

2. In xilinx-v2020.1, 'SPI_NOR_HAS_LOCK' flag is added to 's25fl512s' entry in spi_nor_ids[] table.

 

Considering these changes in xilinx-v2020.1 and your log when the Flash was locked, I wonder you accidentally ran xilinx-v2020.1 kernel. Is it possible to check the kernel version at the time the Flash was locked?

 

Thanks,

Takahiro

 

View solution in original post

18 Replies
huangk
New Contributor II

post the u-boot output:

 

U-Boot 2019.01 (Dec 30 2020 - 12:48:12 +0800)

Board: Xilinx ZynqMP
DRAM: 2 GiB
EL Level: EL2
Chip ID: zu2cg
Watchdog: Started
MMC: mmc@ff160000: 0, mmc@ff170000: 1
Loading Environment from SPI Flash... SF: Detected s25fl512s_256k with page size 256 Bytes, erase size 256 KiB, total 64 MiB
OK
In: serial@ff000000
Out: serial@ff000000
Err: serial@ff000000
Board: Xilinx ZynqMP
Net: ZYNQ GEM: ff0e0000, phyaddr ffffffff, interface rgmii-id
eth0: ethernet@ff0e0000
Hit any key to stop autoboot: 0
ZynqMP> sf erase 0x3000000 +1
No SPI flash selected. Please run `sf probe'
ZynqMP> sf probe
SF: Detected s25fl512s_256k with page size 256 Bytes, erase size 256 KiB, total 64 MiB
ZynqMP> sf erase 0x3000000 +1
SF: Timeout!
SF: 262144 bytes @ 0x3000000 Erased: ERROR
ZynqMP> 

0 Likes
huangk
New Contributor II

more information,

the tool I use to program the flash in linux is " flashcp", it is build from "mtd-utils-aea3641.tar.gz"

in the u-boot, I use command "sf"

 

0 Likes
huangk
New Contributor II

the device tree of QSPI is:

&qspi {
status = "okay";
is-dual = <0>;
num-cs = <1>;

flash@0 {
compatible = "spansion,s25fl512s", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
m25p,fast-read;

#address-cells = <1>;
#size-cells = <1>;

partition@0x00000000 {
label = "boot";
reg = <0x00000000 0x00200000>;
};
partition@0x00200000 {
label = "bootenv";
reg = <0x00200000 0x00040000>;
};
partition@0x00240000 {
label = "pmulti";
reg = <0x00240000 0x02000000>;
};
};
};

0 Likes
AS_36
Moderator
Moderator

Hi,

Can you try to perform the below steps - 

  • Update u-boot source file, build it, and boot the system with the updated u-boot, and please check for protection in SR/CR.
  • In the ‘driver/mtd/spi/spi_flash.c’, read_sr() and read_cr() are the functions that read SR and CR.
  • Add printf in these functions to display register values to log then call them somewhere like end of the spi_flash_scan().

Let us know the results.

Thank you and Regards.

0 Likes
huangk
New Contributor II

 

thank you, the flash can be probed, below is the log from u-boot, I will try your advice

 

ZynqMP> sf erase 0x3000000 11
No SPI flash selected. Please run `sf probe'
ZynqMP> sf probe
SF: Detected s25fl512s_256k with page size 256 Bytes, erase size 256 KiB, total 64 MiB
ZynqMP> sf erase 0x3000000 11
SF: Erase offset/length not multiple of erase size
SF: 17 bytes @ 0x3000000 Erased: ERROR
ZynqMP> sf probe
SF: Detected s25fl512s_256k with page size 256 Bytes, erase size 256 KiB, total 64 MiB
ZynqMP> sf erase 0x3000000 11
SF: Erase offset/length not multiple of erase size
SF: 17 bytes @ 0x3000000 Erased: ERROR
ZynqMP>

0 Likes
huangk
New Contributor II

ZynqMP> sf erase 0x3000000 +11
SF: Timeout!
SF: 262144 bytes @ 0x3000000 Erased: ERROR

0 Likes
huangk
New Contributor II

below is the output of log:

 

ZynqMP> sf erase 0x3000000 +3
SF: erase d8 3 0 0 (3000000)
SF: Timeout!
SF: write page erase timed out
SF: erase failed
SF: 262144 bytes @ 0x3000000 Erased: ERROR

 

where it fails,  it fails at below function when call spi_flash_wait_till_ready


int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
size_t cmd_len, const void *buf, size_t buf_len)
{
struct spi_slave *spi = flash->spi;
unsigned long timeout = SPI_FLASH_PROG_TIMEOUT;
int ret;
#ifdef CONFIG_SPI_GENERIC
u32 flags = 0;
#endif

if (buf == NULL)
timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT;

ret = spi_claim_bus(spi);
if (ret) {
debug("SF: unable to claim SPI bus\n");
return ret;
}

#ifdef CONFIG_SPI_GENERIC
if (flash->dual_flash == SF_DUAL_PARALLEL_FLASH)
flags = flash->spi->flags;
#endif
ret = spi_flash_cmd_write_enable(flash);
if (ret < 0) {
debug("SF: enabling write failed\n");
return ret;
}

#ifdef CONFIG_SPI_GENERIC
if (flash->dual_flash == SF_DUAL_PARALLEL_FLASH)
flash->spi->flags = flags;
#endif
ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf, buf_len);
if (ret < 0) {
debug("SF: write cmd failed\n");
return ret;
}

ret = spi_flash_wait_till_ready(flash, timeout);
if (ret < 0) {
debug("SF: write %s timed out\n",
timeout == SPI_FLASH_PROG_TIMEOUT ?
"program" : "page erase");
return ret;
}

spi_release_bus(spi);

return ret;
}

 

 

0 Likes
huangk
New Contributor II

log of sr and cr when probe and erase in u-boot:

 

Xilinx Zynq MP First Stage Boot Loader

Release 2019.2 Nov 12 2020 - 17:33:53
NOTICE: ATF running on XCZU2CG/silicon v4/RTL5.1 at 0xfffea000
NOTICE: BL31: Secure code at 0x0
NOTICE: BL31: Non secure code at 0x8000000
NOTICE: BL31: v2.0(release):xilinx-v2019.2-dirty
NOTICE: BL31: Built : 20:46:45, Nov 3 2020
PMUFW: v1.1


U-Boot 2019.01 (Feb 04 2021 - 09:17:14 +0800)

Board: Xilinx ZynqMP
DRAM: 2 GiB
EL Level: EL2
Chip ID: zu2cg
Watchdog: Started
MMC: mmc@ff160000: 0, mmc@ff170000: 1
Loading Environment from SPI Flash... SF: read_cr, cmd=53, rs=0x2
SF: read_sr, cmd=5, rs=0x9c
SF: read_sr, cmd=5, rs=0x9f
SF: read_sr, cmd=5, rs=0x9c
spi_flash_decode_fdt: Cannot decode address
SF: Detected s25fl512s_256k with page size 256 Bytes, erase size 256 KiB, total 64 MiB
SF: read_sr, cmd=5, rs=0x9c
SF: read_cr, cmd=53, rs=0x2
sf: end of scan: sr:0x9c, cr:0x2
spi_flash_cmd_read_ops: Byte Mode:0x1
OK
In: serial@ff000000
Out: serial@ff000000
Err: serial@ff000000
Board: Xilinx ZynqMP
Net: ZYNQ GEM: ff0e0000, phyaddr ffffffff, interface rgmii-id
eth0: ethernet@ff0e0000
Hit any key to stop autoboot: 4  0
ZynqMP>
ZynqMP> sf probe
SF: read_cr, cmd=53, rs=0x2
SF: read_sr, cmd=5, rs=0x9c
SF: read_sr, cmd=5, rs=0x9f
SF: read_sr, cmd=5, rs=0x9c
spi_flash_decode_fdt: Cannot decode address
SF: Detected s25fl512s_256k with page size 256 Bytes, erase size 256 KiB, total 64 MiB
SF: read_sr, cmd=5, rs=0x9c
SF: read_cr, cmd=53, rs=0x2
sf: end of scan: sr:0x9c, cr:0x2


ZynqMP> sf erase 0x3000000 +1
SF: erase d8 3 0 0 (3000000)
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: read_sr, cmd=5, rs=0xbf
SF: Timeout!
SF: write page erase timed out
SF: erase failed
SF: 262144 bytes @ 0x3000000 Erased: ERROR
ZynqMP>

0 Likes
huangk
New Contributor II

right after power reset of the board, when I probe the flash by "sf probe", the result is:

sf: end of scan: sr:0x9c, cr:0x2

according to the description of StatusRegister1 and ConfigurationRegister1 in datasheet, seems like the flash block is write protected.

not sure why? and how it happened?

0 Likes
huangk
New Contributor II

is there a way to unlock the flash for this case?

0 Likes
AS_36
Moderator
Moderator

Hi,

SR value = 0x9C indicates Status Register Write Disable (SRWD) and Block Protection (BP) bits are set. Since all three block protection bits are set, it indicates that the entire flash is protected against any program/erase operations.

CR value = 0x02 indicates that Quad bit is set. 

You can remove block protection by programming Status Register with 0x00 value.

However, I would like to request you to go through this Application Note AN200381 - Best Practice for WRR Command for SPI Devices (cypress.com) before programming SR. I would like to inform you that SR/CR registers may get corrupted if an abrupt power failure occurs while performing the WRR operation. The unintended programming of the SRWD and BP bits in your application may also have been caused due to the same reason. Are you performing program operation on the SR/CR registers upon every power up?

Thank you and Regards.

0 Likes
huangk
New Contributor II

thank you for suggestion "You can remove block protection by programming Status Register with 0x00 value."

after write 0x0 to status register, I can erase/write the flash again.

another question of this status register writing, after unlocking it by write 0 to status register, then I program the flash successfully, but if I write 0x0 to status register again, the data I programmed into flash seems like are erased automatically, the read back is all 0xff. If I do not write 0x0 to status register, the data I programmed to flash can be read back correctly.   

Please note that, before I write 0x0 to status register, I did not use the write enable command (WREN 06h),  is this the cause? 

I am doing another longevity testing, so I have not try it.

You asked "Are you performing program operation on the SR/CR registers upon every power up?", 

No, I did not do it. 

I read through the  AN200381,  when I board get this issue, I successfully programmed the flash with ~18MB data, right after programming, I do a system reset in Linux by "reboot".  the  AN200381 mentions the system reset could corrupt the flash register.  Maybe, I should add a delay after the "flashcp" successfully write the flash .

When the issue occurred, the DC power supply to my board has no abnormal noticed, so I want to exclude the external power supply issue.

 

 

 

 

0 Likes
AS_36
Moderator
Moderator

Hi,

AS_36_0-1612523680458.png

Please go through the paragraph marked with red in the above snippet from the datasheet. It says, when Quad mode has been enabled on the flash device, WRR command should always be followed with 16 bits (2 bytes) of data, both for SR and CR registers. If only a a single byte of data is sent, the CR register will go back to its default state, which means the Quad bit will get reset and Quad mode will be disabled. This could be one of the reasons why you are not able to read correct data after trying to program SR with 0x00 after programming the flash.

Could you please tell me exactly why are you trying to program the SR with 0x00 after programming data to your flash? I would like to inform you that unnecessary program operations to the SR/CR registers is not a recommended thing to do.

>> Please note that, before I write 0x0 to status register, I did not use the write enable command (WREN 06h),  is this the cause? 

As you can see in the snippet above, a WREN command is required to be sent before a WRR operation can be performed. Did you mean you missed sending the WREN command? 

>> I read through the  AN200381,  when I board get this issue, I successfully programmed the flash with ~18MB data, right after programming, I do a system reset in Linux by "reboot".  the  AN200381 mentions the system reset could corrupt the flash register.  Maybe, I should add a delay after the "flashcp" successfully write the flash.

The AN only talks about resetting the device during a WRR operation. As per my understanding you are referring to resetting the device after a Page Program operation on the device. Either way, 'flashcp' means all program operations are complete and no embedded operation is running on the flash. Adding a delay after 'flashcp' may not be necessary.

Thank you and Regards.

 

0 Likes
huangk
New Contributor II

>>>Could you please tell me exactly why are you trying to program the SR with 0x00 after programming data to your flash? I would like to inform you that unnecessary program operations to the SR/CR registers is not a recommended thing to do.

thanks, I tried to make the flash be always un-locked, so I was trying to write SR with 0x00 . this ademption is done after I got information that write SR with 0x0 can un-lock the flash.  As you said, this is not necessary.

>>>As you can see in the snippet above, a WREN command is required to be sent before a WRR operation can be performed. Did you mean you missed sending the WREN command? 

yes, I did not send the WREN command before write 0x0 to SR.  

 

>>>The AN only talks about resetting the device during a WRR operation. As per my understanding you are referring to resetting the device after a Page Program operation on the device. Either way, 'flashcp' means all program operations are complete and no embedded operation is running on the flash. Adding a delay after 'flashcp' may not be necessary.

Yes, I am referring to the system resetting after a successfully programming. I did not do the resetting during the page programming with "flashcp" in linux.    Looks like, only reset(power cycle or system reset) during writing the flash could make the flash be locked.  

I do not know why it could happen on my board, as I posted, after a successfully data programming, the flash on my board get locked, and the data reading from the flash after the issue always has no problem. The only thing I do after programming is "reboot".  If something was wrong during the programming, the data read out  should not work and my board should not be able to boot up normally, but actually, my board boot up correctly with the data I programmed right before the locking.  

And, I think I agree with you "Adding a delay after 'flashcp' may not be necessary.",  in this weekend, to reproduce it, I did the test to program the same data with same process when the issue occurred, so far, I have tested about 1700 cycles, the issue has not been reproduced yet.  so, seems like "reset after programming" is not the cause.

Appreciate for your reply, do you think there is any other reasons that could lock the board?  

or, any advice that I can prevent it from being locked? I intended to write 0x0 to SR always right after board reset, is this reasonable?

 

 

 

0 Likes
huangk
New Contributor II

I have not reproduced the same issue in the weekend after programming the flash and resetting about 2500 cycles. 

so, I went back to check the log at the time the flash get locked, I find couple of abnormal information.

at the time when I program the data,   during verifying the data, as below, there is a message "spi-nor spi0.0: trying to lock already unlocked area"

Verifying data: 17880k/18480k (96%)
Verifying data: 17890k/18480k (96%)
Verifying data: 17900k/18480k (96%)
Verifying data: 17910k/18480k (96%)
Verifying data: 17920k/18480k[ 90.566591] spi-nor spi0.0: trying to lock already unlocked area
(96%)
Verifying data: 17930k/18480k (97%)
Verifying data: 17940k/18480k (97%)
Verifying data: 17950k/18480k (97%)
Verifying data: 17960k/18480k (97%)
Verifying data: 17970k/18480k (97%)

 

And, from the kernel log before  I program the data, the SPI flash was detected as: spi-nor

[ 4.027289] spi-nor spi0.0: s25fl512s (65536 Kbytes)
[ 4.032267] 3 fixed-partitions partitions found on MTD device spi0.0
[ 4.038609] Creating 3 MTD partitions on "spi0.0":
[ 4.043395] 0x000000000000-0x000000200000 : "boot"
[ 4.048972] 0x000000200000-0x000000240000 : "bootenv"
[ 4.054642] 0x000000240000-0x000002240000 : "pmulti"

But, normally, at all other times, when the board boot up, the flash is detected as m25p80

[ 3.591252] m25p80 spi0.0: non-uniform erase sector maps are not supported yet.
[ 3.598696] m25p80 spi0.0: s25fl512s (65536 Kbytes)
[ 3.603594] 3 fixed-partitions partitions found on MTD device spi0.0
[ 3.609943] Creating 3 MTD partitions on "spi0.0":
[ 3.614728] 0x000000000000-0x000000200000 : "boot"
[ 3.620059] 0x000000200000-0x000000240000 : "bootenv"
[ 3.625526] 0x000000240000-0x000002240000 : "pmulti"

Maybe, the device tree configured for the flash has problem, but I am not pretty sure of it, at least, it runs well for many cycles, in the weekend, the board is reset about 2500 times, but I did not see the same issue that the flash is detected as "spi-nor". 

flash@0 {
compatible = "spansion,s25fl512s", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
m25p,fast-read;

#address-cells = <1>;
#size-cells = <1>;

partition@0x00000000 {
label = "boot";
reg = <0x00000000 0x00200000>;
};
partition@0x00200000 {
label = "bootenv";
reg = <0x00200000 0x00040000>;
};
partition@0x00240000 {
label = "pmulti";
reg = <0x00240000 0x02000000>;
};
};
};

 

 

 

0 Likes
TakahiroK_16
Employee

Hello,

 

I reviewed the timeline of the 'linux-xlnx' source tree and found:

1. In xilinx-v2020.1, 'm25p80.c' is removed and its content is moved to 'spi-nor.c'

2. In xilinx-v2020.1, 'SPI_NOR_HAS_LOCK' flag is added to 's25fl512s' entry in spi_nor_ids[] table.

 

Considering these changes in xilinx-v2020.1 and your log when the Flash was locked, I wonder you accidentally ran xilinx-v2020.1 kernel. Is it possible to check the kernel version at the time the Flash was locked?

 

Thanks,

Takahiro

 

View solution in original post

huangk
New Contributor II

great, thank you.

yes, I had ever switch to xilinx-v2020.2 code base to try to fix another FPGA issue, in that code base, the linux version is 5.4,  the flash was programmed with this version of linux and the rootfs/tools I built,  then the flash get locked when I program the flash with this version of linux.  below is the version of linux that I use to make the flash locked.

Linux version 5.4.0-xilinx-v2019.2 (root@ubuntu) (gcc version 7.3.1 20180314 (Linaro GCC 7.3-2018.04-rc3)) #1 SMP Fri Jan 15 11:36:08 CST 2021

 

Normally, I use version 4.19 which is built from xilinx-v2019.2

 Linux version 4.19.0-xilinx-v2019.2 (root@ubuntu) (gcc version 7.3.1 20180314 (Linaro GCC 7.3-2018.04-rc3)) #2 SMP Mon Jan 25 13:13:50 CST 2021

 

0 Likes
huangk
New Contributor II

 

the 5.4.0-xilinx-v2019.2 is from  linux-xlnx-xilinx-v2020.2

0 Likes