This hack is derived from this mail by Paul Fertser on openwrt-devel.
- When using 32M flash, the SPI bus needs to be reconfigured to use 4-byte addressing mode, instead of the usual (?) 3-byte mode.
- Issueing a soft reset without this patch leaves the bus in 4-byte mode, which then crashes the system because the SoC tries (and fails) to communicate in 3-byte addressing mode.
- Writing the opcodes brings the SPI back into 3-byte addressing mode, so the SoC can continue communicating after issueing a soft reset.
What I'm not sure about is, whether this causes any issues on boards with 16M flash or less. Leaving the 32bit addressing mode twice doesn't seem to cause any harm.
It is tested on both a ZBT-WG3526 (16M) and Digineo AC1200 Pro (32M), using LEDE master (8459d85). While it fixes the reboot on the AC1200 Pro, it doesn't break the WG3526.
Ideally I'd like to detect the current mode and execute the spi_write
s
conditionally. Also, JESD216B implies in 6.4.19 (JEDEC Basic Flash
Parameter Table) for bits 13:8 (Soft Reset and Rescue Sequence Support),
that the reset sequence used here may not be available (i.e. bit 12 == 0).
(Obviously this needs some cleanup before it can be used anywhere.)
This is unsafe - it may make an intentional soft reset work, but hardware or watchdog reset occurring when the chip is in a boot-incompatible addressing mode will still result in a hang!
If the flash chip is expected to be in 3-byte mode on boot in a particular system, then it needs to stay in 3-byte mode, and the extended address register used to access the full space (though how that register gets cleared may still be an issue); conversely if it expected to be in 4-byte mode on boot, it can never safely leave that mode.
Some SoCs have the ability to drive a reset to the rest of the board; ultimately that or fixing boot addressing mode to the size of the chip actually used may be the best solution, but those are hardware changes.