07-03-2019 07:57 AM - edited 07-03-2019 07:58 AM
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
07-30-2019 08:52 AM - edited 07-30-2019 08:54 AM
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).
07-04-2019 12:11 AM
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?
07-04-2019 08:38 AM
@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.
07-09-2019 07:01 PM
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.
07-10-2019 12:07 PM
@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.
07-10-2019 01:23 PM
@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).
07-10-2019 01:39 PM
@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.
07-10-2019 02:06 PM
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).
07-30-2019 08:52 AM - edited 07-30-2019 08:54 AM
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).