-
Notifications
You must be signed in to change notification settings - Fork 953
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
Save/restore QMI window 1 registers across calls to flash_exit_xip(). #2082
Conversation
This works around the RP2350 ROM reinitialising window 1 even when it does not actually issue an XIP exit sequence to that QSPI device. If no exit sequence is issued, then the original configuration still applies. This is not valid in the case where the ROM *does* issue an XIP exit sequence to the second chip select, because the original mode is no longer valid once the device is in the serial command state. The ROM does this when FLASH_DEVINFO (loaded from OTP, stored in boot RAM) has a nonzero size for chip select 1. To distinguish the two cases, this patch adds getters/setters for FLASH_DEVINFO. If chip select 1 has a nonzero size in FLASH_DEVINFO then the ROM's register changes for window 1 are not reverted, and instead the hardware_flash code makes additional changes to ensure writes also work (as the ROM only reinitialises for reads). This means that, in the case you have opted into ROM support for the second chip select by setting a nonzero CS1 size in FLASH_DEVINFO, the device on chip select 1 will continue to function correctly, but full performance won't be restored until it is reinitialised. The best way to handle this is initialising both chip select devices in your XIP setup function (your boot2).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sweet
I was having a play with powering down flash, and this PR appears to have broken that on RP2350? I have the following function, which works on RP2040 with 2.0.0 and 2.1.0, but on RP2350 only works on 2.0.0, or 2.1.0 with this PR reverted. On 2.1.0 with this PR included it hits a hardfault during the first From looking at the I guess the fix would be to add a void __no_inline_not_in_flash_func(test_flash_powercycle)() {
// Disable Flash
uint8_t txbuf[1] = {0xB9};
uint8_t rxbuf[1] = {0x00};
uint32_t intrs = save_and_disable_interrupts();
flash_do_cmd(txbuf, rxbuf, 1);
busy_wait_at_least_cycles(125000000);
// Won't do anything as flash is powered down
flash_range_erase(0, 4096);
// Enable flash
txbuf[0] = 0xAB;
flash_do_cmd(txbuf, rxbuf, 1);
busy_wait_at_least_cycles(125000000);
restore_interrupts_from_disabled(intrs);
} |
Fixes bug introduced by raspberrypi#2082 where flash_devinfo_get_cs_size would use rom_data_lookup from flash during a __no_inline_not_in_flash_func
* Move rom_data_lookup code into rom_data_lookup_inline Allows ROM data lookup from FLASH/RAM sensitive code * Use rom_data_lookup_inline in flash_devinfo_ptr Fixes bug introduced by #2082 where flash_devinfo_get_cs_size would use rom_data_lookup from flash during a __no_inline_not_in_flash_func
This works around the RP2350 ROM reinitialising window 1 even when it does not actually issue an XIP exit sequence to that QSPI device. If no exit sequence is issued, then the original configuration still applies.
This is not valid in the case where the ROM does issue an XIP exit sequence to the second chip select, because the original mode is no longer valid once the device is in the serial command state. The ROM does this when FLASH_DEVINFO (loaded from OTP, stored in boot RAM) has a nonzero size for chip select 1. To distinguish the two cases, this patch adds getters/setters for FLASH_DEVINFO.
If chip select 1 has a nonzero size in FLASH_DEVINFO then the ROM's register changes for window 1 are not reverted, and instead the hardware_flash code makes additional changes to ensure writes also work (as the ROM only reinitialises for reads).
This means that, in the case you have opted into ROM support for the second chip select by setting a nonzero CS1 size in FLASH_DEVINFO, the device on chip select 1 will continue to function correctly, but full performance won't be restored until it is reinitialised. The best way to handle this is initialising both chip select devices in your XIP setup function (your boot2).