[PATCH v5 20/25] mtd: spi-nor: winbond: Add support for W25Q12RV-M
From: Miquel Raynal <miquel.raynal@bootlin.com>
Date: 2026-09-04 18:14:18
Also in:
linux-doc, lkml
Subsystem:
memory technology devices (mtd), spi nor subsystem, the rest · Maintainers:
Miquel Raynal, Richard Weinberger, Vignesh Raghavendra, Pratyush Yadav, Michael Walle, Linus Torvalds
There is an ID collision with the chip of same density from the JV family. Both chips are very similar in practice, it is mostly a matter of electrical differences (mostly power consumption being lower). As a significant difference, RV chips identify themselves as supporting the new SFDP (rev F) field which forces an alternate write SR2 opcode (0x31). This density wrongly advertizes its size and requires a fixup for that. Reviewed-by: Michael Walle <mwalle@kernel.org> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- + cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id ef7018 + cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer winbond + xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp 534644500a0100ff00080117800000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffe520f9ffffffff0344eb086b083b42bbfeffffffffff 0000ffff44eb0c200f5210d80000142a010186e114c1e96376337a757a75 f7a2d55c39f66dffe930f880000000000000ac0000000000f7f5ffff0f00 0000060d44bd27ed080d + sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp 94b52d6e903a2046e144eab0760384b6932c6fdbfec17eb7336f1778c3898daf /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 70 18 00 00 00 size 16.0 MiB write size 1 page size 256 address nbytes 3 flags HAS_SR_TB | HAS_LOCK | SOFT_RESET | NO_WP | HAS_SR2_CMP_BIT6 opcodes read 0xeb dummy cycles 6 erase 0xd8 program 0x32 SR1 read 0x05 SR2 read 0x35 SR1 write 0x01 SR2 write 0x31 QE SR2 bit 1 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 (16.0 MiB) sector map region (in hex) | erase mask | overlaid ------------------+------------+--------- 00000000-007fffff | [ 3] | no locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-007fffff | unlocked | 64 + dd 'if=/dev/urandom' 'of=./spi_test' 'bs=1M' 'count=2' [ 28.249430] random: crng init done 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 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 spi_read 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 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 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 spi_test + mtd_debug info /dev/mtd0 mtd.type = MTD_NORFLASH mtd.flags = MTD_CAP_NORFLASH mtd.size = 8388608 (8M) mtd.erasesize = 65536 (64K) mtd.writesize = 1 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: 0x800000 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 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 spi_read 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 spi_test + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-007fffff | unlocked | 64 + flash_lock -l /dev/mtd0 + flash_lock -i /dev/mtd0 Device: /dev/mtd0 Start: 0 Len: 0x800000 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 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 spi_read 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 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 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 spi_read 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 spi_read2 48b1df493c0c35b1c6c8a50880c6e10adcd103c383a7324033cb760d20d9acf0 spi_test df6c52ecc59473c5ed9bd10a0479b52ee248adbf7d032aa7cde35e86acd461ca spi_test2 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-007fffff | locked | 64 + flash_lock -u /dev/mtd0 + cat /sys/class/mtd/mtd0/size + size=8388608 + 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=131072 + bps=2 + flash_lock -u /dev/mtd0 + flash_lock -l /dev/mtd0 8126464 4 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-007bffff | unlocked | 62 007c0000-007fffff | locked | 2 + flash_lock -u /dev/mtd0 8126464 2 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-007dffff | unlocked | 63 007e0000-007fffff | locked | 1 + flash_lock -u /dev/mtd0 + flash_lock -l /dev/mtd0 0 4 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-0003ffff | locked | 2 00040000-007fffff | unlocked | 62 + flash_lock -u /dev/mtd0 131072 2 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-0001ffff | locked | 1 00020000-007fffff | unlocked | 63 + all_but_one=126 + flash_lock -u /dev/mtd0 + flash_lock -l /dev/mtd0 131072 126 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-0001ffff | unlocked | 1 00020000-007fffff | locked | 63 + flash_lock -u /dev/mtd0 131072 2 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-0003ffff | unlocked | 2 00040000-007fffff | locked | 62 + flash_lock -u /dev/mtd0 + flash_lock -l /dev/mtd0 0 126 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-007dffff | locked | 63 007e0000-007fffff | unlocked | 1 + flash_lock -u /dev/mtd0 8126464 2 + grep -A4 'locked sectors' /sys/kernel/debug/spi-nor/spi0.0/params locked sectors region (in hex) | status | #sectors ------------------+----------+--------- 00000000-007bffff | locked | 62 007c0000-007fffff | unlocked | 2 --- drivers/mtd/spi-nor/winbond.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index cff6d3f07ed9..2f2c79710241 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c@@ -380,7 +380,7 @@ static const struct flash_info winbond_nor_parts[] = { .no_sfdp_flags = SECT_4K, .flags = SPI_NOR_QUAD_PP | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_HAS_CMP, }, { - /* W25Q128JV-M */ + /* W25Q128JV-M, W25Q12RV-M */ .id = SNOR_ID(0xef, 0x70, 0x18), .name = "w25q128jv", .size = SZ_16M,
@@ -620,6 +620,7 @@ static const struct spi_nor_fixup winbond_fixups[] = { .fixups = &winbond_nor_multi_die_fixups }, { .id = SNOR_ID(0xef, 0x70), .match = winbond_rv_match, .fixups = &winbond_nor_partname_fixups }, + { .id = SNOR_ID(0xef, 0x70, 0x18), .fixups = &w25q128_fixups }, { .id = SNOR_ID(0xef, 0x70, 0x21), .match = winbond_jv_match, .fixups = &winbond_nor_multi_die_fixups }, { .id = SNOR_ID(0xef, 0x70, 0x22), .match = winbond_jv_match,
--
2.54.0