[PATCH 17/25] mtd: spi-nor: winbond: Add support for W25Q33PW-Q/N
From: Miquel Raynal
Date: Wed Sep 09 2026 - 12:22:36 EST
There is an ID collision with chips of same density from the JW family
(which it self conflicted with yet another family). Chips are very
similar in practice, it is mostly a matter of electrical differences
(mostly power consumption being lower) as well as the addition of inline
ECC capability.
16 bytes chunks are protected against single errors. In case a
non-aligned write happens, ECC is locally disabled until the next erase.
Another significant difference is that PW chips identify themselves as
supporting the new SFDP (rev F) QER field which forces an alternate
write SR2 opcode (0x31).
Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx>
---
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
ef6016
+ cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
winbond
+ xxd -p p/sys/us/spi/devices/spi0.0/spi-nor/sfdp
534644500a0100ff00080117800000ffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffe520f9ffffffff0144eb086b083b42bbfeffffffffff
0000ffff44eb0c200f5210d800001432010181e314c2e96376337a757a75
f7a9d55c39f66dffe930f880000000000000ac0000000000f7f5ffff0f00
0000060d44bd27ed080d
+ sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
9b4e76b3ab30d374abbf4cc35893b86e3891acd0c86ba4d8deb111b42f890036 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
+ cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x03
mode cycles 0
dummy cycles 0
1S-1S-2S
opcode 0x3b
mode cycles 0
dummy cycles 8
1S-2S-2S
opcode 0xbb
mode cycles 2
dummy cycles 2
1S-1S-4S
opcode 0x6b
mode cycles 0
dummy cycles 8
1S-4S-4S
opcode 0xeb
mode cycles 2
dummy cycles 4
4S-4S-4S
opcode 0xeb
mode cycles 2
dummy cycles 4
Supported page program modes by the flash
1S-1S-1S
opcode 0x02
1S-1S-4S
opcode 0x32
+ cat /sys/kernel/debug/spi-nor/spi0.0/params
name (null)
id ef 60 16 00 00 00
size 4.00 MiB
write size 16
page size 256
address nbytes 3
flags HAS_SR_TB | HAS_LOCK | SOFT_RESET | ECC | NO_WP | HAS_SR2_CMP_BIT6
opcodes
read 0xeb
dummy cycles 6
erase 0xd8
program 0x32
8D extension repeat
protocols
read 1S-4S-4S
write 1S-1S-4S
register 1S-1S-1S
erase commands
20 (4.00 KiB) [1]
52 (32.0 KiB) [2]
d8 (64.0 KiB) [3]
c7 (4.00 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-003fffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-003fffff | unlocked | 64
+ dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
+ sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_read
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_test
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_test
+ mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 4194304 (4M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0
+ alias 'show_sectors=grep -A4 "locked sectors" /sys/kernel/debug/spi-nor/spi0.0/params'
+ flash_lock -u /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x400000
Lock status: unlocked
Return code: 0
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug write /dev/mtd0 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_read
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_test
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-003fffff | unlocked | 64
+ flash_lock -l /dev/mtd0
+ flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x400000
Lock status: locked
Return code: 1
+ mtd_debug erase /dev/mtd0 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
+ sha256sum spi_read spi_test
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_read
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_test
+ dd 'if=/dev/urandom' 'of=./spi_test2' 'bs=1M' 'count=2'
2+0 records in
2+0 records out
+ mtd_debug write /dev/mtd0 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
+ mtd_debug read /dev/mtd0 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
+ sha256sum spi_read spi_read2 spi_test spi_test2
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_read
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_read2
2fe145f574fac7fcef563647ebaba99ec9226462f5fd520601bbd2cee946529b spi_test
5a4c95f5e812cf8d0123ddb8fc0cece797e41e0ad76ab35340c5680ebdd54073 spi_test2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-003fffff | locked | 64
+ flash_lock -u /dev/mtd0
+ cat /sys/class/mtd/mtd0/size
+ size=4194304
+ cat /sys/class/mtd/mtd0/erasesize
+ bs=65536
+ grep unlocked /sys/kernel/debug/spi-nor/spi0.0/params
+ sed -e 's/.*unlocked | //'
+ nsectors=64
+ ss=65536
+ bps=1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 4063232 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-003dffff | unlocked | 62
003e0000-003fffff | locked | 2
+ flash_lock -u /dev/mtd0 4063232 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-003effff | unlocked | 63
003f0000-003fffff | locked | 1
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 2
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | locked | 2
00020000-003fffff | unlocked | 62
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | locked | 1
00010000-003fffff | unlocked | 63
+ all_but_one=63
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 65536 63
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0000ffff | unlocked | 1
00010000-003fffff | locked | 63
+ flash_lock -u /dev/mtd0 65536 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-0001ffff | unlocked | 2
00020000-003fffff | locked | 62
+ flash_lock -u /dev/mtd0
+ flash_lock -l /dev/mtd0 0 63
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-003effff | locked | 63
003f0000-003fffff | unlocked | 1
+ flash_lock -u /dev/mtd0 4063232 1
+ grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-003dffff | locked | 62
003e0000-003fffff | unlocked | 2
---
drivers/mtd/spi-nor/winbond.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index efa9de1f0f66..60dacfa0eabe 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -373,7 +373,7 @@ static const struct flash_info winbond_nor_parts[] = {
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
}, {
- /* W25Q32DW-P/G, W25Q32FW-G/Q, W25Q32JW-Q/N */
+ /* W25Q32DW-P/G, W25Q32FW-G/Q, W25Q32JW-Q/N, W25Q33PW-Q/N */
.id = SNOR_ID(0xef, 0x60, 0x16),
.name = "w25q32dw",
.size = SZ_4M,
--
2.54.0