added support for SPI Flashes > 16MB using extended address register#247
added support for SPI Flashes > 16MB using extended address register#247MT522 wants to merge 1 commit into
Conversation
|
Can you say which board uses a SPI NOR flash bigger than 128Mbit? I think all the boards I have seen use NAND SPI for sizes beyond 16MB, and then they typically go much bigger. So what is the use case here? And how universal is the extended address register and the bank switching? The idea of this code, in connection with the BootROM, is to stay simple and support a common subset of commands, that are universally usable across different chips. If this is too special, I wonder if using U-Boot's far more elaborate SPI flash support would be preferable, to keep this code here simple and lean. And looking at the code: the diff is hardly readable, it's hard to see what's refactored and what's new code. Can you please try to move the bank switching code into a separate function, and call this from the existing code? So that most of the existing code stays in place, and is just extended by calls to new functions, when needed? If you need refactorings, please do them first in separate patches. |
|
I think it makes sense to strictly avoid using any extended bank switching commands for reading/writing below 16MB. But we can do something else after crossing this boundary (without breaking compatibility with smaller SPI NOR chips). |
|
I was working on a Lichee PI Zero board, and I have soldered a 512Mbit SPI
NOR flash onto it myself.
As for the U-Boot SPI flash interface, you are completely right. there is
no argue in that.
I just found it a little bit tedious in my project to flash the U-boot once
using the sunxi-fel tools and then use the u-boot interface itself to
program the rest of the chip. I patched the tool to be able to program the
complete span of my 64MB memory at once.
the extended address register is universal among all SPI NOR flash
manufacturers with capacities larger than 16MB. In fact, they have even
introduced a 4-Byte addressing mode which is enabled using the SPI command
ENTER_4BYTE.
my current patch does not sabatoge support for smaller chips. It just
inspects the destination address. Should it be larger than 16MB, it sends
the SPI command to switch banks and wraps the address back around 0.
…On Mon, Jun 29, 2026 at 2:39 AM Andre Przywara ***@***.***> wrote:
*apritzel* left a comment (linux-sunxi/sunxi-tools#247)
<#247 (comment)>
Can you say which board uses a SPI NOR flash bigger than 128Mbit? I think
all the boards I have seen use NAND SPI for sizes beyond 16MB, and then
they typically go much bigger. So what is the use case here?
And how universal is the extended address register and the bank switching?
The idea of this code, in connection with the BootROM, is to stay simple
and support a common subset of commands, that are universally usable across
different chips. If this is too special, I wonder if using U-Boot's far
more elaborate SPI flash support would be preferable, to keep this code
here simple and lean.
And looking at the code: the diff is hardly readable, it's hard to see
what's refactored and what's new code. Can you please try to move the bank
switching code into a separate function, and call this from the existing
code? So that most of the existing code stays in place, and is just
extended by calls to new functions, when needed? If you need refactorings,
please do them first in separate patches.
—
Reply to this email directly, view it on GitHub
<#247?email_source=notifications&email_token=AJAVMQ5CBEYLIUKSYP4GYJL5CGQR3A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIOBSG43DSMBXGA32M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-4827690707>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJAVMQ3NUBZY5TQ6RGMO76T5CGQR3AVCNFSNUABDKJSXA33TNF2G64TZHM2DEMBQGU2TAO2JONZXKZJ3GQ3TENZSGA2DMMBRUF3AE>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AJAVMQ5D74PZQCYUPFQDWAL5CGQR3A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIOBSG43DSMBXGA32M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KUZTPN52GK4S7NFXXG>
and Android
<https://github.com/notifications/mobile/android/AJAVMQ33536E65GM6LZJZR35CGQR3A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIOBSG43DSMBXGA32M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2K4ZTPN52GK4S7MFXGI4TPNFSA>.
Download it today!
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
I don't think bank switch or ENTER_4BYTE should be used on V3s, because the BootROM isn't aware of these things, and an unexpected SoC reset without Flash reset will send the system to hell. |
I skimmed through your patch and noticed: uint8_t current_bank = 0xFF;
// <skipped>
if (target_bank != current_bank) {My understanding (without testing it with a real device) is that if the bank is 0 (accessing below 16MB), then the code guarded by the if statement is executed due to having the initial value set to 0xFF. |
you are correct. That's why we resort to the extended address register to switch banks instead of ENTER_4BYTE. By the way, note how the bank automatically switches back to 0 after a read/write operation. The only issue I have not targeted in this patch, is the SoC resetting while programming the higher bytes of the chip. This would retain the bit set in the extended address register. |
Actually, quite on the opposite. The code inside the if statement is always executed. I didn't implement a function to first read the current_bank and skip the block completely if need be (could be added in the future). I just put a dummy value 0xFF inside it at the beginning of the function. Should you look inside the block, you'll see that a WREAR command is issued which sets the current bank of the device to the target bank. So for example if your address is somewhere below 0x1000000, it will reset the EAR. otherwise, the register is set. Also, note that at the end of the function, no matter a read/write operation, the EAR is reset back to 0. This is put there to make sure the next time the SoC powers on and the U-boot tries reading data from the flash, it reads at the correct bank 1 rather than retrieving invalid data sitting at addresses > 0x1000000 |
My comment says that the code inside of the if statement is always executed. So you just confirmed what I said.
And how can we be sure that this is compatible with all older small SPI NOR flash chips? There are many dirt cheap SPI NOR chips sold on Aliexpress or Ebay, which only pretend to be Winbond (sold as WinDbond) and other brand names. Each and every of them may differ in subtle ways. See https://linux-sunxi.org/Bootable_SPI_flash#25Q128FV as an example. If the concept of banks switching is not implemented (since there's no need for that when the size is small) and the relevant commands are not supported, then your patch will ruin someone's day. That's the rationale for #247 (comment) What's the default bank setup after reset on your hardware? I mean, if you switch bank beyond 16MB, does this setup persist after reset? |
One may never change the bank indefinitely. It only sets to bank to 1 during the current operation. It always switches back to 0 at the end. |
You wouldn't need to flash U-Boot, all can stay in RAM, and you control it via a shell script on the host side:
This writes the payload into DRAM, then executes the uploaded U-Boot script, which can do the flash writing. The only downside is that you cannot write the whole 64MB, since not all RAM is available, though you can split it up in chunks and stuff them into the available gaps, then write them separately. And you can flash the first 16MB from sunxi-fel. This would work today without any code changes. If you still want the support, please clean up the patch, and try to address the comments. |
SPI NOR Flashes support address spaces larger than 16MB using an extended address register.
This code switches banks automatically based on the destination address if > 16MB.
After read/write operation, the bank safely switches back to 0.