Flash operations overwrite PSRAM QMI configuration registers #1983
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#1983
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
PSRAM not accessible by the core after a
flash_range_eraseorflash_range_program.Inspection of the QMI interface before and after a call to these SDK functions shows that the 2nd memory region control register (PSRAM,
qmi_hw->m[1]) have had their values modified, rendering the interface inoperative. If the original values are restored by the application manually, communication succeeds and PSRAM data is accessible.In the instance of the PSRAM on the Pimoroni PGA2350, we see the following behavior:
Before flash write
After flash_range_erase / flash_range_program
A more detailed description and test code (Arduino based, sorry, because PSRAM setup is not in the SDK yet) is being tracked in https://github.com/earlephilhower/arduino-pico/issues/2537 .
As a workaround, by using GCC to wrap the flash functions and manually saving/restoring the registers, we're able to both access PSRAM and write to flash. I haven't gone through the RP2350 ROM code, but I would guess as part of the XIP restart after a flash command it is setting what it things are "safe" values to the QMI regions which is great for chip reset, but not so good for when things are already configured.
I suspect this is due to
flash_enable_xip_via_boot2();inflash_range_erase/flash_range_program, which AFAICT boots the boot2 which resets QMI timings. I encountered this earlier but you beat me to making an issue :)An alternative is to copy the code from
flash_range_erase/flash_range_programon RP2350 (making sure to use__no_inline_not_in_flash_func) and ripping outflash_exit_xip_func();andflash_enable_xip_via_boot2();, because I think it is not a required step on RP2350?I could be wrong, but I haven't encountered strange behavior by doing this.
If true, the fix might be a matter of a few
#ifdefs in the SDK.Also, I would suggest to update the documentation for the
hardware_flashlib functions accordingly, as it currently doesn't hint at this behavior as far as I could tell.Looks like CircuitPython also does the manual save-and-restore around their flash ops:
github.com/adafruit/circuitpython@45e0cf10cc/ports/raspberrypi/supervisor/internal_flash.c (L49-L67)I'll look into their cache clean code as well to see if it can help with my other PSRAM/flash cache invalidate issue on the RPI forums.
It's actually the other way round: the default boot2 (XIP setup func) does not configure QMI window 1 (there was an expectation at some point that it might), but the bootrom configures both windows to safe defaults (slow
03h) at the start offlash_exit_xip().I think it would be reasonable for the SDK to save/restore the QMI registers for window 1 over the ROM calls, but this is actually a problem if window 1 received an XIP exit sequence (enabled by
FLASH_DEVINFO_CS1_SIZEbeing nonzero), since the old register settings will no longer be valid if they used a non-serial-prefixed mode.The best-effort fix might be to save/restore
qmi_hw->m[1]across ROM calls if and only ifFLASH_DEVINFO_CS1_SIZEis zero.That would avoid trashing people's registers if they are ignoring the ROM support for the second chip select, but avoid breaking the ROM's reinitialisation of the
m[1]registers in the case where the ROM has issued an XIP exit sequence to the second chip select.The ideal fix is still to (re-) initialise both QSPI devices in the XIP setup, but that's a more substantial piece of work to cover all of the possible cases and combinations.
merged into develop