cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Contributor
Contributor
1,690 Views
Registered: ‎11-17-2014

How do you change a QSPI device from 4 byte addressing back to 3 byte addressing in Petalinux?

Jump to solution

Hi,

I have a couple custom boards that use large QSPI devices containing the FSBL, U-Boot, Bitstream, Petalinux, and a writeable JFFS partition. Since all of this data is pretty large the QSPI is configured to be in 4 byte mode sometime after the FSBL is ran.

I would like to be able to reboot the boards remotely which requires us to put the QSPI devices back into 3 byte addressing so the FSBL can start. 

Is there a command or function I can use in Petalinux to change the QSPI from 4 byte addressing back to 3 byte mode?

 

Thank you

Tags (3)
0 Kudos
Reply
1 Solution

Accepted Solutions
Contributor
Contributor
1,485 Views
Registered: ‎11-17-2014

I was able to solve this a couple weeks ago after learning how the 4.xx kernel driver works. I ended up having to edit a few files spinor.c, spinor.h and, m25p80.c and add a set of shutdown function calls.

Thanks for the help!


@rfs613 wrote:

Certainly, I would appreciate that.

See attached patch file. Note this is against 3.9 or 3.10 kernel. Things have probably changed since then.

 

Also, the chip I was using required a different sequence than yours, so you'll need to change the code for sure. You might also have to transpplant this into the proper QSPI flash driver for your chip (eg. may not be m25p80.c).




View solution in original post

8 Replies
Moderator
Moderator
1,653 Views
Registered: ‎06-27-2017

Hi @asm2750 

May I know if you are facing any issue with 3-byte addressing which is of lower 16MB memory space of flash?

Zynq enables Extended Address register to access the adress width of 4-byte in Linux.

I would like to know if you are facing the any issue when you re-boot? or any other reason?

 

Best Regards
Kranthi
--------------------------
Don't forget to reply, kudo, and accept as solution.
0 Kudos
Reply
Contributor
Contributor
1,640 Views
Registered: ‎11-17-2014

@gudishak wrote:

Hi @asm2750 

May I know if you are facing any issue with 3-byte addressing which is of lower 16MB memory space of flash?

Zynq enables Extended Address register to access the adress width of 4-byte in Linux.

I would like to know if you are facing the any issue when you re-boot? or any other reason?

 


Before I respond I should state I am using a Cypress S25FL512S QSPI device.

I know if I was facing issues with 3-byte addressing the FSBL would not load and run on board power up. I do know the Zynq-7000 microcode on power up and warm resets will only use 3-byte addressing to boot from a QSPI device. https://www.xilinx.com/support/answers/57744.html

Power ups and power cycles are fine and the board boots just as expected. When I run the command "Shutdown -r" in petalinux, it will perform a warm reset but the FSBL will not get loaded and the board will just sit there doing nothing until it is power cycled.

 

However, when I try to do warm resets using the "shutdown -r" command the QSPI device is still in 4-byte addressing mode and will not accept 3-byte addressing mode commands. 

From the Cypress data sheet there is a paragraph about extened address mode:

For backward compatibility to the 3-byte address instructions, the standard instructions can be used in conjunction with the EXTADD Bit in the Bank Address Register (BAR[7]). By default BAR[7] is cleared to 0 (following power up and hardware reset), to enable 3-byte (24-bit) addressing. When set to 1, the legacy commands are changed to require 4 bytes (32 bits) for the address field. The following instructions can be used in conjunction with EXTADD bit to switch from 3 bytes to 4 bytes of address field.

Xilinx AR 57744 also acknoledges this and reccomends resetting the QSPI and Zynq-7000 devices using the external reset pins with an external controller.

Unfortinately I do not have an external controller for board resets, and the QSPI device does not have the reset pin connected to the Zynq for direct control. 

 

That is pretty much why I am looking for is a software solution where I can issue a command to the S25FL512 QSPI to go back to the legacy 3-byte address commands in Petalinux and then call the "Shutdown -r" command to perform a warm reset.

 

0 Kudos
Reply
Scholar
Scholar
1,602 Views
Registered: ‎05-28-2013

As you have noted, a hardware solution is preferred, but if you have no choice, a software workaround is the only option. Naturally, this only works for "clean" reboot under software control. It will not help if the CPU resets due to watchdog, or an external voltage monitor, or even a user pressing a "reset" button on the board.

 

Looking at the datasheet for the S25FL512S device, page 108, section 9.9.1 and 9.9.2 appear to be relevant. It looks like you need to send the "Mode Bit Reset" command (0xFF). Something like this should do the trick:

        code = 0xFF; // OPCODE_MBR
        rc = spi_write_then_read(flash->spi, &code, 1, NULL, 0);
        printk("flash mode bit reset = %d\n", rc);

In order to trigger that command at reboot, you can use register_reboot_notifier() from the probe() method of your QSPI driver.

Contributor
Contributor
1,584 Views
Registered: ‎11-17-2014

@rfs613 wrote:

As you have noted, a hardware solution is preferred, but if you have no choice, a software workaround is the only option. Naturally, this only works for "clean" reboot under software control. It will not help if the CPU resets due to watchdog, or an external voltage monitor, or even a user pressing a "reset" button on the board.

 

Looking at the datasheet for the S25FL512S device, page 108, section 9.9.1 and 9.9.2 appear to be relevant. It looks like you need to send the "Mode Bit Reset" command (0xFF). Something like this should do the trick:

        code = 0xFF; // OPCODE_MBR
        rc = spi_write_then_read(flash->spi, &code, 1, NULL, 0);
        printk("flash mode bit reset = %d\n", rc);

In order to trigger that command at reboot, you can use register_reboot_notifier() from the probe() method of your QSPI driver.


That seems like the path of least resistance. I'm having a hard time having spi.h appear in my rootfs. Do you know what package needs to be added in the kernel? All I seem to get in /usr/linux/spi/ is  spidev.h.

0 Kudos
Reply
Scholar
Scholar
1,575 Views
Registered: ‎05-28-2013

@asm2750 wrote:


That seems like the path of least resistance. I'm having a hard time having spi.h appear in my rootfs. Do you know what package needs to be added in the kernel? All I seem to get in /usr/linux/spi/ is  spidev.h.


Are you trying to write a userspace program to send the "Mode Bit Reset" command? Since the flash chip is "claimed" by the QSPI driver, I don't think this approach will work. Also, you would need to unmount the flash, which is only possible if you rootfs is a ramdisk (eg. not the QSPI flash).

 

I would recommend putting the code in the kernel itself. There is a point, long after user types "shutdown -r", but before the kernel actually resets the CPU. That's the place to hook into. The kernel function "register_reboot_notifier()" is designed to for exactly this sort of thing. I can send you my old patch as a hint, though you will need to make changes (different kernel version, different flash chip, different command you need to send).

 

Contributor
Contributor
1,568 Views
Registered: ‎11-17-2014

@rfs613 wrote:

@asm2750 wrote:


That seems like the path of least resistance. I'm having a hard time having spi.h appear in my rootfs. Do you know what package needs to be added in the kernel? All I seem to get in /usr/linux/spi/ is  spidev.h.


Are you trying to write a userspace program to send the "Mode Bit Reset" command? Since the flash chip is "claimed" by the QSPI driver, I don't think this approach will work. Also, you would need to unmount the flash, which is only possible if you rootfs is a ramdisk (eg. not the QSPI flash).

 

I would recommend putting the code in the kernel itself. There is a point, long after user types "shutdown -r", but before the kernel actually resets the CPU. That's the place to hook into. The kernel function "register_reboot_notifier()" is designed to for exactly this sort of thing. I can send you my old patch as a hint, though you will need to make changes (different kernel version, different flash chip, different command you need to send).

 


Certainly, I would appreciate that.

0 Kudos
Reply
Scholar
Scholar
1,558 Views
Registered: ‎05-28-2013

Certainly, I would appreciate that.

See attached patch file. Note this is against 3.9 or 3.10 kernel. Things have probably changed since then.

 

Also, the chip I was using required a different sequence than yours, so you'll need to change the code for sure. You might also have to transpplant this into the proper QSPI flash driver for your chip (eg. may not be m25p80.c).

Contributor
Contributor
1,486 Views
Registered: ‎11-17-2014

I was able to solve this a couple weeks ago after learning how the 4.xx kernel driver works. I ended up having to edit a few files spinor.c, spinor.h and, m25p80.c and add a set of shutdown function calls.

Thanks for the help!


@rfs613 wrote:

Certainly, I would appreciate that.

See attached patch file. Note this is against 3.9 or 3.10 kernel. Things have probably changed since then.

 

Also, the chip I was using required a different sequence than yours, so you'll need to change the code for sure. You might also have to transpplant this into the proper QSPI flash driver for your chip (eg. may not be m25p80.c).




View solution in original post